给定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
定义一个函数,whether(class_, attribute) 返回一个元组,该元组包含源代码中定义或子类化 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")
我想在反思 Plone 时使用它,其中每个对象都有数百个方法,并且按类而不只是按字母顺序对它们进行排序非常有用。
当然,在 Python 中你不能总是合理地知道,但在大多数静态代码的常见情况下获得好的答案会很好。
Given an instance of some class in Python, it would be useful to be able to determine which line of source code defined each method and property (e.g. to implement 1). For example, given a module 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
define a function whither(class_, attribute) returning a tuple containing the filename, class, and line in the source code that defined or subclassed attribute
. This means the definition in the class body, not the latest assignment due to overeager dynamism. It's fine if it returns 'unknown' for some attributes.
>>> 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")
I want to use this while introspecting Plone, where every object has hundreds of methods and it would be really useful to sort through them organized by class and not just alphabetically.
Of course, in Python you can't always reasonably know, but it would be nice to get good answers in the common case of mostly-static code.
发布评论
评论(3)
您正在寻找未记录的函数
inspect.classify_class_attrs(cls)
。 向其传递一个类,它将返回一个元组列表('name','kind',例如'method'或'data',定义类,属性)
。 如果您需要特定实例中所有内容的信息,您将需要做额外的工作。例子:
You are looking for the undocumented function
inspect.classify_class_attrs(cls)
. Pass it a class and it will return a list of tuples('name', 'kind' e.g. 'method' or 'data', defining class, property)
. If you need information on absolutely everything in a specific instance you'll have to do additional work.Example:
如果没有静态分析,这或多或少是不可能的,即使这样,它也不会总是有效。 您可以通过检查函数的代码对象来获取定义函数的行以及在哪个文件中,但除此之外,您无能为力。
inspect
模块可以帮助解决这个问题。 所以:但是考虑一下:
或更糟糕的是:
特别是在后一种情况下,您想要或期望得到什么?
This is more-or-less impossible without static analysis, and even then, it won't always work. You can get the line where a function was defined and in which file by examining its code object, but beyond that, there's not much you can do. The
inspect
module can help with this. So:But consider:
Or worse:
Especially in the latter case, what do you want or expect to get?
您正在寻找 inspect 模块,特别是
inspect.getsourcefile()< /code> 和
inspect.getsourcelines()
。 例如a.py:
考虑到Python的动态特性,在更复杂的情况下这样做可能根本不可能......
You are looking for the inspect module, specifically
inspect.getsourcefile()
andinspect.getsourcelines()
. For examplea.py:
Given the dynamic nature of Python, doing this for more complicated situations may simply not be possible...