我正在编写一个Python工具,它可以遍历AST来提取一些数据。为了提高它的可用性,我想扩展ast.AST类,因此基于它的每个节点都具有相同的能力,例如获取父节点、子节点、兄弟姐妹等。
在Python中,我可以将其他属性、方法和缓存的属性直接附加到3.9+:
def _attach_to(cls, name=None):
def decorator(func):
func_name = name or func.__name__
cached = cached_property(func)
setattr(cls, func_name, cached)
# see https://bugs.python.org/issue38524
cached.__set_name__(cls, func_name) # noqa: WPS609
return func
return decorator但是在我愿意支持的Python3.8上,我不能将额外的东西附加到ast.AST上,它是一个内置的:
TypeError: can't set attributes of built-in/extension type '_ast.AST'所以我探索了不同的东西:
使用补丁函数(如ast.AST
ast.AST进行修补(例如unittest.mock.patch:它似乎不会影响从原始的ast.AST.__mro__:__mro__ is ast.AST.__bases__:无法在子类上设置built-inast.AST更改为自己的ExtendedAST (从ast.AST继承))中的子类:抱怨对象布局差异<代码>H 223F 224是否有一种方法可以动态地向内建类添加属性/方法/属性?
发布于 2021-09-14 16:34:48
我最终找到了一些有用的东西:我声明了一个ExtendedAST类,但没有将它作为ast.AST的子类,而是将它作为一个“混合体”,并将其附加到所有不同节点的类的__bases__中:
for name, member in inspect.getmembers(ast):
if name != "AST" and inspect.isclass(member):
if ast.AST in member.__bases__:
new_bases = list(member.__bases__)
new_bases.append(ExtendedAST)
member.__bases__ = tuple(new_bases)https://stackoverflow.com/questions/69181489
复制相似问题