Conselho sobre Python: Portabilidade da chamada de função introspectiva


14

No Python, você pode usar a dirfunção em qualquer objeto para obter uma lista dos nomes de suas funções de instância:

>>> 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']

Eu estou querendo saber se isso poderia ser uma técnica útil de golfe em um programa do que chama várias funções com nomes longos. Nesse caso, eu poderia criar uma função de seleção de função F:

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

Agora, suponha que eu tenha uma string se que queira armazenar o resultado da capitalização de sua primeira letra na variável c. Então, em vez de c=s.capitalize(),eu, observe que capitalizeestá na posição 33 da lista acima e faça o seguinte:

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

que atribui 'Abc'a c.

Minha pergunta é se isso provavelmente funcionará a maior parte do tempo. Em particular,

  • Posso sempre contar com a lista sendo lexicograficamente classificada por valores ASCII?
  • Há muitas alterações na lista de disponíveis entre versões secundárias?
  • Existem diferenças entre implementações?

Além disso, alguém já usou isso antes no PPCG?


Eu já vi coisas semelhantes feitas com JavaScript e C #.
Peter Taylor

2
Você também pode fazer isso com builtins: dir(__builtins__). E aqui está uma função alternativa: F=lambda o,i:getattr(o,dir(o)[i]).
grc

Observe também que, dependendo de quais funções você planeja usar, você pode adicionar ()ao final da seguinte Fforma: F=lambda o,i:eval('o.'+dir(o)[i])()Em seguida c=F('abc',33), atribuirá 'Abc' a c.
FryAmTheEggman

Respostas:


6

A partir da documentação :

A lista resultante é classificada em ordem alfabética

Quanto às diferenças, acho que você terá que verificar (e especificar sua resposta provavelmente é uma boa idéia). Existem diferenças claras entre o python 2 e 3, por exemplo, que __nonzero__foi renomeado para __bool__.

Eu nunca ouvi falar de diferenças entre implementações, mas não consigo encontrar nenhuma referência sobre isso.

Eu não acho que isso tenha sido usado antes, em parte, porque raramente poupa personagens para fazer algo como:

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

Você precisaria usar várias funções diferentes dir()para que isso valha a pena.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.