Python-Ratschlag: Portabilität des introspektiven Funktionsaufrufs

14

In Python können Sie die dirFunktion für jedes Objekt verwenden, um eine Liste der Namen seiner Instanzfunktionen abzurufen:

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

Ich frage mich, ob dies eine nützliche Golftechnik in einem Programm sein könnte, als mehrere Funktionen mit langem Namen aufzurufen. In einem solchen Fall könnte ich eine Funktionsauswahlfunktion erstellen F:

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

Angenommen, ich habe eine Zeichenfolge sund möchte das Ergebnis der Großschreibung des ersten Buchstabens in der Variablen speichern c. Anstelle von c=s.capitalize(),könnte ich dann feststellen, dass capitalizeauf Position 33 in der obigen Liste und folgendermaßen vorgehen:

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

die Abtretungsempfänger 'Abc'zu c.

Meine Frage ist, ob dies wahrscheinlich die meiste Zeit funktioniert. Im Speziellen,

  • Kann ich immer darauf zählen, dass die Liste lexikografisch nach ASCII-Werten sortiert ist?
  • Gibt es viele Änderungen an der Liste der verfügbaren Versionen zwischen den Nebenversionen?
  • Gibt es Unterschiede zwischen Implementierungen?

Hat das schon mal jemand bei PPCG benutzt?

Feersum
quelle
Ich habe ähnliche Dinge mit JavaScript und C # gesehen.
Peter Taylor
2
Sie können mit builtins tun dies auch: dir(__builtins__). Und hier ist eine alternative Funktion: F=lambda o,i:getattr(o,dir(o)[i]).
Grc
Beachten Sie auch, dass Sie je nach den Funktionen, die Sie verwenden möchten, das folgende ()an das Ende von hinzufügen können F: F=lambda o,i:eval('o.'+dir(o)[i])()Dann c=F('abc',33)wird 'Abc' zugewiesen c.
FryAmTheEggman

Antworten:

6

Aus der Dokumentation :

Die resultierende Liste ist alphabetisch sortiert

Ich denke, Sie müssen die Unterschiede überprüfen (und es ist wahrscheinlich eine gute Idee, in Ihrer Antwort anzugeben). Es gibt deutliche Unterschiede zwischen Python 2 und 3, auf das beispielsweise __nonzero__umbenannt wurde __bool__.

Ich habe noch nie von Unterschieden zwischen Implementierungen gehört, kann aber keine Referenzen dazu finden.

Ich glaube nicht, dass dies zuvor zum Teil verwendet wurde, da Sie dadurch selten Zeichen sparen, wenn Sie etwas tun wie:

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

Sie müssten verschiedene Funktionen von verwenden dir(), damit sich dies lohnt.

FryAmTheEggman
quelle