【发布时间】:2019-06-08 13:41:44
【问题描述】:
我正在尝试提取创建特定变量的行号。这听起来像一个简单的问题,毕竟我可以遍历代码行并尝试搜索,或者做一个正则表达式。但这可能是一个错误的行号,如果可能的话,我更愿意按原样解析 Python 代码并获得一个真实的行号。
这是我所拥有的:
class MyClass:
"""
MyClass.
Notice that we do override the name class attribute.
class MyClass:
name = "a real name"
"""
name = "the true name"
def __iinit__(self):
pass
感谢inspect.getsourcelines,我可以获得类的行(一个文件中可能定义了多个类,它们可能都有不同的name 属性)。我需要的是找到为此类定义 name 类属性的行号。使用ast? dis?我不反对任何建议。
这对于调试很有用。在我的例子中,class 属性是一个包含一些格式化文本的多行字符串,当出现问题时我需要用文件名和行号报告错误。所以我宁愿知道属性是在哪里定义的,而不仅仅是它的值。
感谢您的帮助,
编辑
根据@bsbueno 的回答,我试图想出一些简单的东西,不会干扰我的原始设计,可能是这样流动的。我正在创建一个简单的元类,它唯一的工作就是注册这个属性。请注意,我仍然在 Child 类的函数调用中“包装”该属性,因此这个解决方案并不理想,并且比在单独的命名空间中定义 register 函数好不了多少。总而言之,我所做的并不是最好的选择,但它提供了另一个示例,可能对其他人有用,或者我希望:
import sys
class MetaRegister(type):
def __prepare__(name, bases, **kwds):
return {"register": MetaRegister.register}
@staticmethod
def register(value):
frame = sys._getframe().f_back
file = frame.f_globals["__file__"]
line = frame.f_lineno
print(f"Calling register {file}:{line}: {value!r}")
return value
class Parent(metaclass=MetaRegister):
option = None
class Child(Parent):
option = register(3)
在创建其他类(Parent 和 Child)之前调用元类的 __prepare__ 方法。它在它们的命名空间中添加了一些东西(在本例中为register 函数)。这直接在Child 的类主体中使用。 register 函数(它实际上是元类本身的一个静态方法)并没有做太多的事情,只是在第一次调用它的地方打印。这对我来说已经足够了,尽管正如我所说,这是一个可能感觉解决不了多少的解决方案。发表意见!
【问题讨论】:
-
__iinit__?双i? -
我猜这是个错误,抱歉。