Python에서 개체의 정규화된 클래스 이름 가져오기
로깅 목적으로 Python 개체의 정규화된 클래스 이름을 검색하려고 합니다. (완전화된 경우 패키지 및 모듈 이름을 포함하는 클래스 이름을 의미합니다.)
에 대해 알고 있습니다.x.__class__.__name__하지만 패키지와 모듈을 얻을 수 있는 간단한 방법이 있습니까?
다음 프로그램과 함께
#!/usr/bin/env python
import foo
def fullname(o):
klass = o.__class__
module = klass.__module__
if module == 'builtins':
return klass.__qualname__ # avoid outputs like 'builtins.str'
return module + '.' + klass.__qualname__
bar = foo.Bar()
print(fullname(bar))
그리고.Bar로 정의된.
class Bar(object):
def __init__(self, v=42):
self.val = v
산출물은
$ ./prog.py
foo.Bar
만약 당신이 여전히 파이썬 2에 갇혀 있다면, 당신은 사용해야 할 것입니다.__name__대신에__qualname__중첩 클래스 - 클래스에 대한 정보가 부족합니다.Bar클래스에 내포된Foo로 표시됩니다.Bar대신에Foo.Bar:
def fullname(o):
klass = o.__class__
module = klass.__module__
if module == '__builtin__':
return klass.__name__ # avoid outputs like '__builtin__.str'
return module + '.' + klass.__name__
제공된 답변은 중첩된 클래스를 처리하지 않습니다.
Python 3.3(PEP 3155) 이후로는__qualname__대신 학급의__name__그렇지 않으면, 클래스는
class Foo:
class Bar: # this one
pass
정당하게 나타날 것입니다.Bar대신에Foo.Bar.
(계속 연결해야 합니다.__module__별도로 -__qualname__모듈 이름을 포함하지 않습니다.)
다음은 그렉 베이컨의 훌륭한 답변을 바탕으로 한 것이지만 몇 가지 추가적인 확인 사항이 있습니다.
__module__수 있습니다.None(문서에 따르면), 그리고 같은 유형에 대해서도.str그럴 수 있다.__builtin__(로그 등에 표시하지 않을 수도 있음).다음은 두 가지 가능성을 모두 확인하는 방법입니다.
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__
(확인할 수 있는 더 나은 방법이 있을 수 있습니다.__builtin__위의 내용은 str이 항상 사용 가능하고 모듈이 항상 사용 가능하다는 사실에 의존합니다.__builtin__)
python 3.7의 경우 다음을 사용합니다.
".".join([obj.__module__, obj.__name__])
가져오기:
package.subpackage.ClassName
사용을 고려해 보십시오.inspect다음과 같은 기능을 가진 모듈getmodule다음과 같은 것들을 찾고 있습니다.
>>>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'>
일부 사람들(예: https://stackoverflow.com/a/16763814/5766934) )은 다음과 같이 주장합니다.__qualname__보다 낫습니다__name__다음은 차이점을 보여주는 예입니다.
$ 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
기본 제공 기능에 대해서도 올바르게 작동합니다.
>>> print(full_name_with_qualname(print))
builtins.print
>>> import builtins
>>> builtins.print
<built-in function print>
__module__할 수 있을 겁니다
시도:
>>> import re
>>> print re.compile.__module__
re
이 사이트는 다음을 제안합니다.__package__Python 3.0에서 작동할 수 있습니다. 그러나 여기에 나와 있는 예제는 Python 2.5.2 콘솔에서 작동하지 않습니다.
이것은 해킹이지만 저는 2.6을 지원하며 간단한 것이 필요합니다.
>>> from logging.handlers import MemoryHandler as MH
>>> str(MH).split("'")[1]
'logging.handlers.MemoryHandler'
이 항목에서는 정규화된 이름을 가져오는 데 관심이 있으므로 동일한 패키지에 있는 기본 모듈과 함께 상대 가져오기를 사용할 때 발생하는 함정이 있습니다.예: 아래 모듈 설정:
$ 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
다음은 동일한 모듈을 다르게 가져온 결과를 보여주는 출력입니다.
$ 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
이 경로를 때 는 hum을 봅니다.Baz.__module__전체 이름을 사용하는 두 번째 가져오기에서는 "foo.baz"와 동일하게 표시됩니다.
전체 이름을 어딘가에 유지하는 경우 해당 클래스에 대한 상대적 가져오기를 피하는 것이 좋습니다.
Bellows는 클래스, 인스턴스, 메서드, 함수, 내장 및 사용자 정의 모두에 대해 테스트된 Greg Bacon의 답변을 개선한 것입니다.
def fullname(o):
try:
# if o is a class or function, get module directly
module = o.__module__
except AttributeError:
# then get module from o's class
module = o.__class__.__module__
try:
# if o is a class or function, get name directly
name = o.__qualname__
except AttributeError:
# then get o's class name
name = o.__class__.__qualname__
# if o is a method of builtin class, then module will be None
if module == 'builtins' or module is None:
return name
return module + '.' + name
이것은 Greg Bacon과 MB가 정규 클래스 이름을 사용하기 위해 답변을 수정한 것입니다.질문에 정규화된 클래스 이름이 묻었습니다.Python 3.8로 테스트되었습니다.
def fullname(obj: object) -> str:
"""Return the full name of the given object using its module and qualified class names."""
# Ref: https://stackoverflow.com/a/66508248/
module_name, class_name = obj.__class__.__module__, obj.__class__.__qualname__
if module_name in (None, str.__class__.__module__):
return class_name
return module_name + "." + class_name
여기에 있는 어떤 대답도 저에게는 통하지 않았습니다.의 경우, 저는 새로운 의 Python 2.7과만 있었습니다.object 수업. 수업.
def get_qualified_python_name_from_class(model):
c = model.__class__.__mro__[0]
name = c.__module__ + "." + c.__name__
return name
내 솔루션은 다음과(와)
def fullname(obj) -> str:
if type(obj).__qualname__ != "type":
# obj is instance
return ".".join(
[
obj.__class__.__module__,
obj.__class__.__qualname__,
]
)
# obj is not instance
return ".".join([obj.__module__, obj.__qualname__])
# not instance
>>> print(fullname(datetime))
"datetime.datetime"
# instance
>>> print(fullname(datetime.now())
"datetime.datetime"
# instance
>>> print(fullname(3))
"builtins.int"
언급URL : https://stackoverflow.com/questions/2020014/get-fully-qualified-class-name-of-an-object-in-python
'programing' 카테고리의 다른 글
| 질문이 있는 경우 Oracle sql이 true를 반환합니다. (0) | 2023.06.12 |
|---|---|
| R에서 루프 작동 속도 향상 (0) | 2023.06.12 |
| Node.js + TypeScript:스크립트 컴파일 코드 형식의 구문이 분명하지 않습니다. (0) | 2023.06.07 |
| TypeScript에서 빈 개체 유형 정의 (0) | 2023.06.07 |
| JPA에서 TINYINT 열 유형 생성 (0) | 2023.06.07 |