如何确定Python类的每个属性和方法是在哪里定义的?

2024-04-20 16:39:33 发布

您现在位置:Python中文网/ 问答频道 /正文

给定Python中某个类的实例,能够确定哪个源代码行定义了每个方法和属性(例如实现1),将非常有用。例如,给定一个模块实验室在

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

定义一个函数,该函数返回一个元组,该元组包含定义或子类化attribute的源代码中的文件名、类和行。这意味着类主体中的定义,而不是由于过于急切的动态性而导致的最新赋值。如果它对某些属性返回“unknown”就可以了。在

^{pr2}$

我想在自省Plone时使用这个方法,在Plone中,每个对象都有数百个方法,按类组织而不仅仅是按字母顺序进行排序将非常有用。在

当然,在Python中,您不可能总是合理地知道,但是在大多数静态代码的常见情况下,最好能得到好的答案。在


Tags: 模块实例方法函数self属性定义object
3条回答

您正在查找未记录的函数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)

但请考虑:

^{pr2}$

或者更糟:

some_cls = ab.A
some_string_var = 'another_instance_attribute'
setattr(some_cls, some_string_var, None)

尤其是在后一种情况下,你想要或期望得到什么?在

您正在查找inspect模块,特别是inspect.getsourcefile()和{}。例如

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)

考虑到Python的动态特性,在更复杂的情况下这样做可能根本不可能。。。在

相关问题 更多 >