파이썬 클래스의 각 속성과 방법이 어디에 정의되는지 어떻게 결정 하시겠습니까?
-
20-08-2019 - |
문제
Python의 일부 클래스 인스턴스가 주어지면 어떤 소스 코드 라인을 결정할 수 있습니다. 한정된 각 방법과 속성 (예 : 구현해야 할 것입니다 1). 예를 들어, 모듈 AB.PY가 주어졌습니다
class A(object):
z = 1
q = 2
def y(self): pass
def x(self): pass
class B(A):
q = 4
def x(self): pass
def w(self): pass
whither (class_, attribute) filename, class 및 line을 포함하는 튜플을 반환하는 함수 정의 소스 코드에서 정의 또는 서브 클래스를 정의합니다. attribute
. 이것은 과잉 역동으로 인한 최신 과제가 아니라 클래스 본문의 정의를 의미합니다. 일부 속성에 대해 '알 수없는'을 반환하면 괜찮습니다.
>>> a = A()
>>> b = B()
>>> b.spigot = 'brass'
>>> whither(a, 'z')
("ab.py", <class 'a.A'>, [line] 2)
>>> whither(b, 'q')
("ab.py", <class 'a.B'>, 8)
>>> whither(b, 'x')
("ab.py", <class 'a.B'>, 9)
>>> whither(b, 'spigot')
("Attribute 'spigot' is a data attribute")
나는 모든 객체에 수백 가지 방법을 가지고 있으며 알파벳순으로뿐만 아니라 클래스별로 구성하는 것이 실제로 유용 할 것입니다.
물론, 파이썬에서는 항상 합리적으로 알 수는 없지만 대부분 정적 코드의 공동 사례에서 좋은 답변을 얻는 것이 좋을 것입니다.
해결책 2
문서화되지 않은 기능을 찾고 있습니다 inspect.classify_class_attrs(cls)
. 수업을 전달하면 튜플 목록을 반환합니다. ('name', 'kind' e.g. 'method' or 'data', defining class, property)
. 특정 인스턴스의 모든 것에 대한 정보가 필요한 경우 추가 작업을 수행해야합니다.
예시:
>>> import inspect
>>> import pprint
>>> import calendar
>>>
>>> hc = calendar.HTMLCalendar()
>>> hc.__class__.pathos = None
>>> calendar.Calendar.phobos = None
>>> pprint.pprint(inspect.classify_class_attrs(hc.__class__))
[...
('__doc__',
'data',
<class 'calendar.HTMLCalendar'>,
'\n This calendar returns complete HTML pages.\n '),
...
('__new__',
'data',
<type 'object'>,
<built-in method __new__ of type object at 0x814fac0>),
...
('cssclasses',
'data',
<class 'calendar.HTMLCalendar'>,
['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']),
('firstweekday',
'property',
<class 'calendar.Calendar'>,
<property object at 0x98b8c34>),
('formatday',
'method',
<class 'calendar.HTMLCalendar'>,
<function formatday at 0x98b7bc4>),
...
('pathos', 'data', <class 'calendar.HTMLCalendar'>, None),
('phobos', 'data', <class 'calendar.Calendar'>, None),
...
]
다른 팁
정적 분석 없이는 불가능하거나 불가능하지만, 그럼에도 불구하고 항상 작동하지는 않습니다. 함수가 정의 된 줄과 코드 객체를 검사하여 파일을 얻을 수 있지만 그 외에도 할 수있는 일은 많지 않습니다. 그만큼 inspect
모듈은 이것에 도움이 될 수 있습니다. 그래서:
import ab
a = ab.A()
meth = a.x
# So, now we have the method.
func = meth.im_func
# And the function from the method.
code = func.func_code
# And the code from the function!
print code.co_firstlineno, code.co_filename
# Or:
import inspect
print inspect.getsource(meth), inspect.getfile(meth)
그러나 고려 :
def some_method(self):
pass
ab.A.some_method = some_method
ab.A.some_class_attribute = None
또는 더 나쁜 :
some_cls = ab.A
some_string_var = 'another_instance_attribute'
setattr(some_cls, some_string_var, None)
특히 후자의 경우, 당신은 무엇을 원하거나 기대합니까?
당신은 찾고 있습니다 검사 특히 모듈 inspect.getsourcefile()
그리고 inspect.getsourcelines()
. 예를 들어
A.Py :
class Hello(object):
def say(self):
print 1
>>> from a import Hello
>>> hi = Hello()
>>> inspect.getsourcefile(hi.say)
a.py
>>> inspect.getsourcelines(A, foo)
([' def say(self):\n print 1\n'], 2)
파이썬의 역동적 인 특성을 감안할 때, 더 복잡한 상황을 위해 이것을하는 것은 단순히 불가능할 수 있습니다 ...