Câu trả lời:
Với chương trình sau
#! /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)
và Bar
được định nghĩa là
class Bar(object):
def __init__(self, v=42):
self.val = v
đầu ra là
$ ./prog.py
foo.Bar
o.__class__.__module__
bao giờ khác với o.__module__
?
".".join([o.__module__, o.__name__])
cho Python3
AttributeError: 'AttributeError' object has no attribute '__module__'
Các câu trả lời được cung cấp không đối phó với các lớp lồng nhau. Mặc dù nó không có sẵn cho đến Python 3.3 ( PEP 3155 ), bạn thực sự muốn sử dụng __qualname__
lớp. Cuối cùng (3.4? PEP 395 ), __qualname__
cũng sẽ tồn tại cho các mô-đun để xử lý các trường hợp mô-đun được đổi tên (nghĩa là khi nó được đổi tên thành __main__
).
Type.__module__ + '.' + Type.__qualname__
.
__qualname__
vẫn chỉ phân giải thành tên lớp
Xem xét sử dụng inspect
mô-đun có các chức năng giống như getmodule
có thể là những gì đang tìm kiếm:
>>>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()
trả về các đối tượng mô-đun - tên lớp không đủ điều kiện. Trong thực tế, inspect
mô-đun cung cấp không có chức năng nào thực sự sẽ giải quyết câu hỏi này. Câu trả lời này là một câu trả lời không. </facepalm>
Đây là một câu trả lời dựa trên câu trả lời xuất sắc của Greg Bacon, nhưng với một vài kiểm tra bổ sung:
__module__
có thể là None
(theo các tài liệu), và đối với một loại giống như str
nó có thể __builtin__
(mà bạn có thể không muốn xuất hiện trong nhật ký hoặc bất cứ điều gì). Các kiểm tra sau cho cả hai khả năng đó:
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__
(Có thể có một cách tốt hơn để kiểm tra __builtin__
. Ở trên chỉ dựa vào thực tế là str luôn có sẵn và mô-đun của nó luôn luôn __builtin__
)
Đối với python3.7 tôi sử dụng:
".".join([obj.__module__, obj.__name__])
Bắt:
package.subpackage.ClassName
obj
phải là một lớp chứ không phải là một thể hiện đối tượng.
__module__
sẽ làm các mẹo.
Thử:
>>> import re
>>> print re.compile.__module__
re
Trang web này gợi ý rằng __package__
có thể hoạt động cho Python 3.0; Tuy nhiên, các ví dụ đưa ra sẽ không hoạt động trong bảng điều khiển Python 2.5.2 của tôi.
"%s.%s" % (x.__class__.__module__, x.__class__.__name__)
Đây là một hack nhưng tôi đang hỗ trợ 2.6 và chỉ cần một cái gì đó đơn giản:
>>> from logging.handlers import MemoryHandler as MH
>>> str(MH).split("'")[1]
'logging.handlers.MemoryHandler'
__repr__()
thực hiện trong lớp kiểm tra ( và trên __str__()
không được overriden). Vô dụng trong hầu hết các trường hợp.
Một số người (ví dụ: https://stackoverflow.com/a/16763814/5766934 ) cho rằng điều đó __qualname__
tốt hơn __name__
. Dưới đây là một ví dụ cho thấy sự khác biệt:
$ 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
Lưu ý, nó cũng hoạt động chính xác cho các bản dựng:
>>> print(full_name_with_qualname(print))
builtins.print
>>> import builtins
>>> builtins.print
<built-in function print>
Vì sự quan tâm của chủ đề này là để có được các tên đủ điều kiện, đây là một cạm bẫy xảy ra khi sử dụng nhập khẩu tương đối cùng với mô-đun chính hiện có trong cùng một gói. Ví dụ, với thiết lập mô-đun bên dưới:
$ 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
Đây là đầu ra hiển thị kết quả của việc nhập cùng một mô-đun khác nhau:
$ 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
Khi hum nhập thanh sử dụng đường dẫn tương đối, thanh chỉ xem Baz.__module__
là "baz", nhưng trong lần nhập thứ hai sử dụng tên đầy đủ, thanh sẽ thấy giống như "foo.baz".
Nếu bạn đang duy trì các tên đủ điều kiện ở đâu đó, tốt hơn là tránh nhập khẩu tương đối cho các lớp đó.
Không có câu trả lời nào ở đây làm việc cho tôi. Trong trường hợp của tôi, tôi đã sử dụng Python 2.7 và biết rằng tôi sẽ chỉ làm việc với object
các lớp newstyle .
def get_qualified_python_name_from_class(model):
c = model.__class__.__mro__[0]
name = c.__module__ + "." + c.__name__
return name