Совет по Python: переносимость интроспективного вызова функции


14

В Python вы можете использовать dirфункцию для любого объекта, чтобы получить список имен его функций экземпляра:

>>> dir('abc')
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__','__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

Мне интересно, может ли это быть полезной техникой игры в гольф, чем вызов нескольких функций с длинными именами. В таком случае я мог бы создать функцию выбора функции F:

F=lambda o,i:eval('o.'+dir(o)[i])

Теперь предположим, что у меня есть строка, sи я хочу сохранить результат использования заглавной буквы в первой переменной c. Тогда вместо c=s.capitalize(),я мог бы отметить, что capitalizeнаходится в позиции 33 в приведенном выше списке и сделать следующее:

s='abc'
c=G(s,33)()

который назначает 'Abc'на c.

Мой вопрос заключается в том, может ли это работать большую часть времени. Особенно,

  • Могу ли я всегда рассчитывать на лексикографическую сортировку списка по значениям ASCII?
  • Много ли изменений в списке доступных между второстепенными версиями?
  • Существуют ли различия между реализациями?

Кроме того, кто-нибудь использовал это раньше на PPCG?


Я видел похожие вещи, сделанные с помощью JavaScript и C #.
Питер Тейлор

2
Вы также можете сделать это с помощью встроенных команд: dir(__builtins__). А вот альтернативная функция: F=lambda o,i:getattr(o,dir(o)[i]).
grc

Также обратите внимание, что в зависимости от того, какие функции вы планируете использовать, вы можете добавить ()в конец, Fнапример, так: F=lambda o,i:eval('o.'+dir(o)[i])()Затем c=F('abc',33)присвойте 'Abc' c.
FryAmTheEggman

Ответы:


6

Из документации :

Полученный список отсортирован по алфавиту

Что касается различий, я думаю, вам придется проверить (и указание в вашем ответе, вероятно, хорошая идея). Существуют четкие различия между Python 2 и 3, например, __nonzero__был переименован в __bool__.

Я никогда не слышал о каких-либо различиях между реализациями, но я не могу найти никаких ссылок на это.

Я не думаю, что это использовалось ранее отчасти, потому что это редко спасет вас от каких-либо персонажей при выполнении чего-то вроде:

F=str.capitalize
s='abc'
c=F(s)

Вам нужно будет использовать несколько различных функций, dir()чтобы это того стоило.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.