Odpowiedzi:
Z następującym programem
#! /usr/bin/env python
import foo
def fullname(o):
# o.__module__ + "." + o.__class__.__qualname__ is an example in
# this context of H.L. Mencken's "neat, plausible, and wrong."
# Python makes no guarantees as to whether the __module__ special
# attribute is defined, so we take a more circumspect approach.
# Alas, the module name is explicitly excluded from __qualname__
# in Python 3.
module = o.__class__.__module__
if module is None or module == str.__class__.__module__:
return o.__class__.__name__ # Avoid reporting __builtin__
else:
return module + '.' + o.__class__.__name__
bar = foo.Bar()
print fullname(bar)
i Bar
zdefiniowany jako
class Bar(object):
def __init__(self, v=42):
self.val = v
wyjście jest
$ ./prog.py
foo.Bar
o.__class__.__module__
kiedykolwiek różni się od o.__module__
?
".".join([o.__module__, o.__name__])
dla Pythona3
AttributeError: 'AttributeError' object has no attribute '__module__'
Podane odpowiedzi nie dotyczą klas zagnieżdżonych. Chociaż nie jest dostępna przed wersją Python 3.3 ( PEP 3155 ), naprawdę chcesz użyć __qualname__
tej klasy. Ostatecznie (3.4? PEP 395 ) __qualname__
będzie również istnieć dla modułów do obsługi przypadków, w których nazwa modułu zostanie zmieniona (tj. Kiedy zostanie zmieniona na __main__
).
Type.__module__ + '.' + Type.__qualname__
.
__qualname__
nadal występuje tylko nazwa klasy
Rozważ użycie inspect
modułu, który ma funkcje, takie jak getmodule
to, czego szukasz:
>>>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'>
inspect.getmodule()
zwraca obiekty modułu - nie w pełni kwalifikowane nazwy klas. W rzeczywistości inspect
moduł nie zapewnia żadnej funkcjonalności, która faktycznie rozwiązałaby to pytanie. Ta odpowiedź nie jest odpowiedzią. </facepalm>
Oto jedna oparta na doskonałej odpowiedzi Grega Bacona, ale z kilkoma dodatkowymi kontrolami:
__module__
może być None
(zgodnie z dokumentacją), a także dla typu takiego jak str
może być __builtin__
(którego możesz nie chcieć pojawiać się w logach lub czymkolwiek). Poniższe testy sprawdzają obie te możliwości:
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__
(Może być lepszy sposób sprawdzenia __builtin__
. Powyższe opiera się tylko na fakcie, że str jest zawsze dostępny, a jego moduł jest zawsze __builtin__
)
Dla pythona3.7 używam:
".".join([obj.__module__, obj.__name__])
Zdobywanie:
package.subpackage.ClassName
obj
musi to być klasa, a nie instancja obiektu.
__module__
załatwi sprawę.
Próbować:
>>> import re
>>> print re.compile.__module__
re
Ta witryna sugeruje, że __package__
może to działać w przypadku Pythona 3.0; Jednak podane tam przykłady nie będą działać na mojej konsoli Pythona 2.5.2.
"%s.%s" % (x.__class__.__module__, x.__class__.__name__)
To hack, ale obsługuję 2.6 i potrzebuję tylko czegoś prostego:
>>> from logging.handlers import MemoryHandler as MH
>>> str(MH).split("'")[1]
'logging.handlers.MemoryHandler'
__repr__()
implementacji w sprawdzonej klasy ( i na __str__()
nie są nadpisane). W większości przypadków bezużyteczne.
Niektórzy (np. Https://stackoverflow.com/a/16763814/5766934 ) twierdzą, że __qualname__
jest lepsze niż __name__
. Oto przykład, który pokazuje różnicę:
$ 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
Uwaga, działa również poprawnie dla buildów:
>>> print(full_name_with_qualname(print))
builtins.print
>>> import builtins
>>> builtins.print
<built-in function print>
Ponieważ celem tego tematu jest uzyskanie w pełni kwalifikowanych nazw, oto pułapka, która pojawia się podczas używania importu względnego wraz z głównym modułem istniejącym w tym samym pakiecie. Np. Z poniższą konfiguracją modułu:
$ 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
Oto dane wyjściowe przedstawiające wynik importowania tego samego modułu w inny sposób:
$ export PYTHONPATH=/tmp/fqname
$ python /tmp/fqname/main.py
foo.baz
foo.baz
$ python /tmp/fqname/foo/bar.py
baz
$ python /tmp/fqname/foo/hum.py
baz
foo.baz
Kiedy hum importuje pasek przy użyciu ścieżki względnej, bar widzi Baz.__module__
po prostu „baz”, ale w drugim imporcie, który używa pełnej nazwy, bar widzi to samo, co „foo.baz”.
Jeśli gdzieś utrwalasz w pełni kwalifikowane nazwy, lepiej unikać importu względnego dla tych klas.
Żadna z odpowiedzi tutaj nie zadziałała. W moim przypadku używałem Pythona 2.7 i wiedziałem, że będę pracował tylko z object
klasami newstyle .
def get_qualified_python_name_from_class(model):
c = model.__class__.__mro__[0]
name = c.__module__ + "." + c.__name__
return name