首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扩展ast.AST

扩展ast.AST
EN

Stack Overflow用户
提问于 2021-09-14 16:34:48
回答 1查看 116关注 0票数 1

我正在编写一个Python工具,它可以遍历AST来提取一些数据。为了提高它的可用性,我想扩展ast.AST类,因此基于它的每个节点都具有相同的能力,例如获取父节点、子节点、兄弟姐妹等。

在Python中,我可以将其他属性、方法和缓存的属性直接附加到3.9+:

代码语言:javascript
复制
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上,它是一个内置的:

代码语言:javascript
复制
TypeError: can't set attributes of built-in/extension type '_ast.AST'

所以我探索了不同的东西:

使用补丁函数(如ast.AST

  • patching:)对ast.AST进行修补(例如unittest.mock.patch:它似乎不会影响从原始的ast.AST.__mro____mro__ is ast.AST.__bases__:无法在子类上设置built-in
    • iterating属性并将ast.AST更改为自己的ExtendedAST (从ast.AST继承))中的子类:抱怨对象布局差异<代码>H 223F 224

是否有一种方法可以动态地向内建类添加属性/方法/属性?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-14 16:34:48

我最终找到了一些有用的东西:我声明了一个ExtendedAST类,但没有将它作为ast.AST的子类,而是将它作为一个“混合体”,并将其附加到所有不同节点的类的__bases__中:

代码语言:javascript
复制
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)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69181489

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档