Saran Python: Portabilitas panggilan fungsi introspektif

14

Dengan Python, Anda bisa menggunakan dirfungsi pada objek apa pun untuk mendapatkan daftar nama fungsi instansinya:

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

Saya bertanya-tanya apakah ini bisa menjadi teknik golf yang berguna dalam suatu program daripada memanggil beberapa fungsi yang telah lama disebut. Dalam kasus seperti itu, saya bisa membuat fungsi pemilihan fungsi F:

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

Sekarang anggaplah saya memiliki string sdan saya ingin menyimpan hasil dari huruf kapital pertama dalam variabel c. Maka alih-alih c=s.capitalize(),saya dapat mencatat bahwa capitalizeberada pada posisi 33 dalam daftar di atas dan lakukan hal berikut:

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

yang ditugaskan 'Abc'untuk c.

Pertanyaan saya adalah apakah ini mungkin berhasil sebagian besar waktu. Khususnya,

  • Bisakah saya selalu mengandalkan daftar yang diurutkan secara leksikografis berdasarkan nilai ASCII?
  • Apakah ada banyak perubahan pada daftar yang tersedia di antara versi minor?
  • Apakah ada perbedaan antara implementasi?

Juga, adakah yang pernah menggunakan ini sebelumnya di PPCG?

feersum
sumber
Saya telah melihat hal serupa dilakukan dengan JavaScript dan C #.
Peter Taylor
2
Anda juga dapat melakukan ini dengan builtin: dir(__builtins__). Dan inilah fungsi alternatif: F=lambda o,i:getattr(o,dir(o)[i]).
grc
Juga perhatikan bahwa tergantung pada fungsi yang Anda rencanakan untuk digunakan, Anda bisa menambahkannya ()di akhir Fseperti ini: F=lambda o,i:eval('o.'+dir(o)[i])()Kemudian c=F('abc',33)akan menetapkan 'Abc' ke c.
FryAmTheEggman

Jawaban:

6

Dari dokumentasi :

Daftar yang dihasilkan diurutkan berdasarkan abjad

Adapun perbedaannya, saya pikir Anda harus memeriksa (dan menentukan jawaban Anda mungkin ide yang bagus). Ada perbedaan yang jelas antara python 2 dan 3, misalnya, __nonzero__diubah namanya menjadi __bool__.

Saya belum pernah mendengar perbedaan antara implementasi, tetapi saya tidak dapat menemukan referensi tentang ini.

Saya tidak berpikir ini telah digunakan sebelumnya sebagian karena jarang akan menyelamatkan Anda karakter daripada melakukan sesuatu seperti:

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

Anda perlu menggunakan beberapa fungsi berbeda dir()agar ini layak dilakukan.

FryAmTheEggman
sumber