Untuk tujuan logging saya ingin mengambil nama kelas yang memenuhi syarat dari objek Python. (Dengan memenuhi syarat yang saya maksud nama kelas termasuk nama paket dan modul.)
Saya tahu tentang x.__class__.__name__
, tetapi apakah ada metode sederhana untuk mendapatkan paket dan modul?
python
python-datamodel
Hanno S.
sumber
sumber
o.__class__.__module__
pernah berbeda dario.__module__
?".".join([o.__module__, o.__name__])
untuk Python3AttributeError: 'AttributeError' object has no attribute '__module__'
Jawaban yang diberikan tidak berhubungan dengan kelas bertingkat. Meskipun tidak tersedia hingga Python 3.3 ( PEP 3155 ), Anda benar-benar ingin menggunakan
__qualname__
kelas tersebut. Pada akhirnya (3.4? PEP 395 ),__qualname__
juga akan ada untuk modul untuk menangani kasus-kasus di mana modul tersebut diganti namanya (yaitu ketika namanya diubah__main__
).sumber
Type.__module__ + '.' + Type.__qualname__
.__qualname__
masih hanya menyelesaikan ke nama kelasPertimbangkan untuk menggunakan
inspect
modul yang memiliki fungsi sepertigetmodule
yang mungkin Anda cari:>>>import inspect >>>import xml.etree.ElementTree >>>et = xml.etree.ElementTree.ElementTree() >>>inspect.getmodule(et) <module 'xml.etree.ElementTree' from 'D:\tools\python2.5.2\lib\xml\etree\ElementTree.pyc'>
sumber
inspect.getmodule()
mengembalikan objek modul - nama kelas tidak sepenuhnya memenuhi syarat. Faktanya,inspect
modul tidak menyediakan fungsionalitas apa pun yang benar-benar menjawab pertanyaan ini. Jawaban ini bukan jawaban.</facepalm>
Ini satu berdasarkan jawaban luar biasa Greg Bacon, tetapi dengan beberapa pemeriksaan tambahan:
__module__
bisaNone
(menurut dokumen), dan juga untuk tipe sepertistr
itu__builtin__
(yang mungkin tidak Anda inginkan muncul di log atau apa pun). Pemeriksaan berikut untuk kedua kemungkinan tersebut:def fullname(o): module = o.__class__.__module__ if module is None or module == str.__class__.__module__: return o.__class__.__name__ return module + '.' + o.__class__.__name__
(Mungkin ada cara yang lebih baik untuk memeriksanya
__builtin__
. Hal di atas hanya bergantung pada fakta bahwa str selalu tersedia, dan modulnya selalu__builtin__
)sumber
Untuk python3.7 saya menggunakan:
".".join([obj.__module__, obj.__name__])
Mendapatkan:
sumber
obj
harus kelas daripada contoh objek.__module__
akan berhasil.Mencoba:
>>> import re >>> print re.compile.__module__ re
Situs ini menyarankan bahwa
__package__
mungkin bekerja untuk Python 3.0; Namun, contoh yang diberikan di sana tidak akan berfungsi di bawah konsol Python 2.5.2 saya.sumber
"%s.%s" % (x.__class__.__module__, x.__class__.__name__)
Ini adalah peretasan tetapi saya mendukung 2.6 dan hanya membutuhkan sesuatu yang sederhana:
>>> from logging.handlers import MemoryHandler as MH >>> str(MH).split("'")[1] 'logging.handlers.MemoryHandler'
sumber
__repr__()
pelaksanaan di kelas diperiksa ( dan pada__str__()
tidak menjadi overriden). Tidak berguna dalam banyak kasus.Beberapa orang (misalnya https://stackoverflow.com/a/16763814/5766934 ) berpendapat bahwa
__qualname__
itu lebih baik daripada__name__
. Berikut adalah contoh yang menunjukkan perbedaannya:$ cat dummy.py class One: class Two: pass $ python3.6 >>> import dummy >>> print(dummy.One) <class 'dummy.One'> >>> print(dummy.One.Two) <class 'dummy.One.Two'> >>> def full_name_with_name(klass): ... return f'{klass.__module__}.{klass.__name__}' >>> def full_name_with_qualname(klass): ... return f'{klass.__module__}.{klass.__qualname__}' >>> print(full_name_with_name(dummy.One)) # Correct dummy.One >>> print(full_name_with_name(dummy.One.Two)) # Wrong dummy.Two >>> print(full_name_with_qualname(dummy.One)) # Correct dummy.One >>> print(full_name_with_qualname(dummy.One.Two)) # Correct dummy.One.Two
Catatan, ini juga berfungsi dengan benar untuk buildin:
>>> print(full_name_with_qualname(print)) builtins.print >>> import builtins >>> builtins.print <built-in function print>
sumber
Karena minat dari topik ini adalah mendapatkan nama yang sepenuhnya memenuhi syarat, berikut ini adalah kesalahan yang terjadi saat menggunakan impor relatif bersama dengan modul utama yang ada dalam paket yang sama. Misalnya, dengan pengaturan modul di bawah ini:
$ cat /tmp/fqname/foo/__init__.py $ cat /tmp/fqname/foo/bar.py from baz import Baz print Baz.__module__ $ cat /tmp/fqname/foo/baz.py class Baz: pass $ cat /tmp/fqname/main.py import foo.bar from foo.baz import Baz print Baz.__module__ $ cat /tmp/fqname/foo/hum.py import bar import foo.bar
Berikut adalah keluaran yang menunjukkan hasil pengimporan modul yang sama secara berbeda:
Saat impor hum bar menggunakan jalur relatif, bar
Baz.__module__
hanya dilihat sebagai "baz", tetapi pada import kedua yang menggunakan nama lengkap, bar terlihat sama dengan "foo.baz".Jika Anda mempertahankan nama yang sepenuhnya memenuhi syarat di suatu tempat, lebih baik hindari impor relatif untuk kelas tersebut.
sumber
Tidak ada jawaban di sini yang berhasil untuk saya. Dalam kasus saya, saya menggunakan Python 2.7 dan tahu bahwa saya hanya akan bekerja dengan
object
kelas gaya baru.def get_qualified_python_name_from_class(model): c = model.__class__.__mro__[0] name = c.__module__ + "." + c.__name__ return name
sumber