Diberikan string sebagai input pengguna ke fungsi Python, saya ingin mendapatkan objek kelas dari itu jika ada kelas dengan nama itu di namespace yang saat ini didefinisikan. Pada dasarnya, saya ingin implementasi untuk fungsi yang akan menghasilkan hasil seperti ini:
class Foo:
pass
str_to_class("Foo")
==> <class __main__.Foo at 0x69ba0>
Apakah ini mungkin?
Jawaban:
Ini tampaknya paling sederhana.
sumber
Ini bisa bekerja:
sumber
def str_to_class(str): return vars()[str]
?Anda dapat melakukan sesuatu seperti:
sumber
globals()
... hal lain yang harus dihindariglobals()
bisa dibilang jauh lebih buruk daripadaeval
, dan tidak benar-benar lebih buruk daripadasys.modules[__name__]
AFAIK.Anda menginginkan kelas
Baz
, yang hidup dalam modulfoo.bar
. Dengan Python 2.7, Anda ingin menggunakanimportlib.import_module()
, karena ini akan membuat transisi ke Python 3 lebih mudah:Dengan Python <2.7:
Menggunakan:
sumber
Ini secara akurat menangani kelas gaya lama dan gaya baru.
sumber
Saya telah melihat bagaimana django menangani ini
django.utils.module_loading memiliki ini
Anda bisa menggunakannya seperti
import_string("module_path.to.all.the.way.to.your_class")
sumber
Ya, Anda bisa melakukan ini. Dengan asumsi kelas Anda ada di namespace global, sesuatu seperti ini akan melakukannya:
sumber
Dalam hal eksekusi kode arbitrer, atau nama yang diberikan pengguna yang tidak diinginkan, Anda dapat memiliki daftar nama fungsi / kelas yang dapat diterima, dan jika input cocok dengan satu dalam daftar, itu dievaluasi.
PS: Saya tahu .... agak terlambat .... tapi untuk siapa saja yang tersandung di masa depan.
sumber
Menggunakan importlib bekerja paling baik untuk saya.
Ini menggunakan notasi string dot untuk modul python yang ingin Anda impor.
sumber
Jika Anda benar-benar ingin mengambil kelas yang Anda buat dengan string, Anda harus menyimpan (atau menggunakan kata yang tepat, referensi ) dalam kamus. Setelah semua, itu juga akan memungkinkan untuk memberi nama kelas Anda di tingkat yang lebih tinggi dan menghindari mengekspos kelas yang tidak diinginkan.
Contoh, dari game di mana kelas aktor didefinisikan dengan Python dan Anda ingin menghindari kelas umum lainnya yang bisa dijangkau oleh input pengguna.
Pendekatan lain (seperti dalam contoh di bawah) akan membuat seluruh kelas baru, yang memegang di
dict
atas. Ini akan:Contoh:
Ini mengembalikan saya:
Eksperimen menyenangkan lain yang harus dilakukan dengan itu adalah menambahkan metode yang mengasamkan
ClassHolder
sehingga Anda tidak pernah kehilangan semua kelas yang Anda lakukan: ^)sumber