Python introspection : 객체 속성의 '소화되지 않은'목록을 얻는 방법은 무엇입니까?
-
11-07-2019 - |
문제
다음 코드
import types
class A:
class D:
pass
class C:
pass
for d in dir(A):
if type(eval('A.'+d)) is types.ClassType:
print d
출력
C
D
코드에서 이러한 클래스가 정의 된 순서대로 어떻게 출력을 얻습니까? 즉
D
C
expect.getSource (a)를 사용하고 파싱하는 것 외에 다른 방법이 있습니까?
해결책
그만큼 inspect
모듈도 있습니다 findsource
기능. 객체가 정의되는 소스 라인과 선 번호의 튜플을 반환합니다.
>>> import inspect
>>> import StringIO
>>> inspect.findsource(StringIO.StringIO)[1]
41
>>>
그만큼 findsource
함수는 실제로 소스 파일을 트로프를 검색하고 클래스 객체가 주어지면 후보자를 찾습니다.
메소드, 기능-, 트레이스 백-, 프레임 또는 코드-오브젝트가 주어지면 단순히 co_firstlineno
(포함 된) 코드-개체의 속성.
다른 팁
구문 분석은 이미 검사에서 당신을 위해 완료되었습니다. inspect.findsource
, 클래스 정의에 대한 모듈을 검색하고 소스 및 줄 번호를 반환합니다. 해당 라인 번호를 정렬하면 (별도의 모듈로 정의 된 클래스를 분할해야 할 수도 있음) 올바른 순서를 제공해야합니다.
그러나이 기능은 문서화되지 않은 것으로 보이며 정규 표현식을 사용하여 선을 찾으므로 너무 신뢰할 수 없습니다.
또 다른 옵션은 메타 클라스 또는 객체에 정보를 암시 적으로 또는 명시 적으로 주문하는 다른 방법을 사용하는 것입니다. 예를 들어:
import itertools, operator
next_id = itertools.count().next
class OrderedMeta(type):
def __init__(cls, name, bases, dct):
super(OrderedMeta, cls).__init__(name, bases, dct)
cls._order = next_id()
# Set the default metaclass
__metaclass__ = OrderedMeta
class A:
class D:
pass
class C:
pass
print sorted([cls for cls in [getattr(A, name) for name in dir(A)]
if isinstance(cls, OrderedMeta)], key=operator.attrgetter("_order"))
그러나 이것은 상당히 방해적인 변화입니다 (OrderedMeta에 관심이있는 클래스의 메타 클래스를 설정해야합니다).
아니요, 원하는 순서로 해당 속성을 얻을 수 없습니다. Python 속성은 삽입 순서에 대한 인식이없는 DICT (읽기 : HASHMAP)에 저장됩니다.
또한, 나는 단순히 말함으로써 평가의 사용을 피할 것입니다.
if type(getattr(A, d)) is types.ClassType:
print d
당신의 루프에서. 키/값 쌍을 통해 반복 할 수도 있습니다. A.__dict__
Afaik, 아니요 -*가 없습니다. 이것은 모든 클래스의 속성이 사전에 저장되기 때문입니다 (아시다시피, 순서대로).
*: 실제로 가능할 수도 있지만 데코레이터 나 메타 클래스 해킹이 필요합니다. 그 관심사 중 하나가 당신을합니까?
나는 여기서 glib을하려고하지는 않지만 소스의 수업을 알파벳순으로 정리하는 것이 가능합니까? 한 파일에 많은 클래스가있을 때 자체적으로 유용 할 수 있습니다.