Saya telah melihat banyak contoh orang yang mengekstraksi semua kelas dari sebuah modul, biasanya sekitar seperti:
# foo.py
class Foo:
pass
# test.py
import inspect
import foo
for name, obj in inspect.getmembers(foo):
if inspect.isclass(obj):
print obj
Luar biasa.
Tapi saya tidak tahu bagaimana cara mendapatkan semua kelas dari modul saat ini .
# foo.py
import inspect
class Foo:
pass
def print_classes():
for name, obj in inspect.getmembers(???): # what do I do here?
if inspect.isclass(obj):
print obj
# test.py
import foo
foo.print_classes()
Ini mungkin sesuatu yang sangat jelas, tetapi saya belum dapat menemukan apa pun. Adakah yang bisa membantu saya?
python
reflection
inspect
mcccclean
sumber
sumber
"class"
? Mengapa itu tidak berhasil?Jawaban:
Coba ini:
Dalam konteks Anda:
Dan bahkan lebih baik:
Karena
inspect.getmembers()
butuh predikat.sumber
from optparse import OptionParser
) modul-modul tersebut termasuk dalam daftar cetak. Bagaimana saya bisa menghindarinya?inspect.getmembers(sys.modules[__name__], lambda member: member.__module__ == __name__ and isnpect.isclass)
dict(inspect.getmembers(sys.modules[__name__])) == globals()
selaluTrue
, jadi mengapa impor?inspect.getmembers(sys.modules[__name__], lambda member: inspect.isclass(member) and member.__module__ == __name__
isclass
.Bagaimana dengan
?
sumber
isinstance(obj, types.ClassType)
pudb
menjalankan program Anda dengan cara ini, yang menghasilkan kode menggunakansys.modules
melanggar secara acak saat debugging.globals()
tampaknya sedikit jelek, tetapi tampaknya jauh lebih dapat diandalkan.Saya tidak tahu apakah ada cara yang 'tepat' untuk melakukannya, tetapi cuplikan Anda ada di jalur yang benar: tambahkan saja
import foo
ke foo.py, lakukaninspect.getmembers(foo)
, dan itu akan berfungsi dengan baik.sumber
Saya bisa mendapatkan semua yang saya butuhkan dari
dir
built in plusgetattr
.Meskipun, itu tampak seperti bola rambut:
sumber
Perhatikan bahwa modul browser kelas Python stdlib menggunakan analisis sumber statis, sehingga hanya berfungsi untuk modul yang didukung oleh
.py
file nyata .sumber
Jika Anda ingin memiliki semua kelas, yang termasuk dalam modul saat ini, Anda dapat menggunakan ini:
Jika Anda menggunakan jawaban Nadia dan Anda mengimpor kelas lain pada modul Anda, kelas itu akan diimpor juga.
Jadi itu sebabnya
member.__module__ == __name__
ditambahkan ke predikat yang digunakan padais_class_member
. Pernyataan ini memeriksa apakah kelas benar-benar milik modul.Predikat adalah fungsi (bisa dipanggil), yang mengembalikan nilai boolean.
sumber
Solusi lain yang bekerja di Python 2 dan 3:
sumber
Ini adalah baris yang saya gunakan untuk mendapatkan semua kelas yang telah didefinisikan dalam modul saat ini (yaitu tidak diimpor). Agak panjang menurut PEP-8 tetapi Anda bisa mengubahnya sesuai keinginan Anda.
Ini memberi Anda daftar nama kelas. Jika Anda ingin objek kelas itu sendiri tetap saja obj.
Ini lebih bermanfaat dalam pengalaman saya.
sumber
sumber
Saya pikir Anda dapat melakukan sesuatu seperti ini.
jika Anda membutuhkan kelas sendiri
sumber
Saya sering menemukan diri saya menulis utilitas baris perintah di mana argumen pertama dimaksudkan untuk merujuk ke salah satu dari banyak kelas yang berbeda. Misalnya
./something.py feature command —-arguments
, di manaFeature
kelas dancommand
metode pada kelas itu. Inilah kelas dasar yang membuatnya mudah.Asumsinya adalah bahwa kelas dasar ini berada di direktori bersama semua subkelasnya. Anda kemudian dapat memanggil
ArgBaseClass(foo = bar).load_subclasses()
yang akan mengembalikan kamus. Misalnya, jika direktori terlihat seperti ini:Dengan asumsi
feature.py
mengimplementasikanclass Feature(ArgBaseClass)
, maka doa di atasload_subclasses
akan kembali{ 'feature' : <Feature object> }
. Hal yang samakwargs
(foo = bar
) akan diteruskan keFeature
kelas.sumber