python - 如何使用反射或解析读取Python类中声明成员的顺序(禁止元类替换)?

标签 python class python-2.7 reflection

避免太快/无效重复标记的重要说明 - 请在回答前阅读。

不要建议任何更改原始类代码的解决方案 - 不允许更改代码反射和解析。

  1. How to read class attributes in the same order as declared?是解决方案 - 它需要替换所有类中的元类并增加开销 - 绝对不是反射使用。

  2. 考虑到我不能或不想更改代码来扫描类(class)成员顺序。类可以具有或已经具有未知的元类 - 不可能无缘无故地添加元类或增加性能开销。

  3. 只能使用反射或解析文件。


我想避免编写解析器并按声明顺序读取类属性。

在 Python 中如何使用反射(和简单的解析)?

让我举个例子:

class A(object):
  b = 1
  a = 1
  c = 1

dir(A) 给出字母顺序,但要求是声明顺序。如何做到这一点 - 请帮忙?

最佳答案

你必须求助于解析。您不需要在这里编写解析器; ast module可以为您做到这一点。

使用 ast.parse() 解析源代码,然后遍历生成的树:

class ClassOrder(ast.NodeVisitor):
    identifiers = None
    def visit_ClassDef(self, node):
        self.identifiers = []
        for child in node.body:
            if isinstance(child, ast.Assign):
                for target in child.targets:
                    self.visit(target)
            elif isinstance(child, ast.FunctionDef):
                self.identifiers.append(child.name)
    def visit_Name(self, node):
        if self.identifiers is not None:
            self.identifiers.append(node.id)

tree = ast.parse(sourcecode)
order = ClassOrder()
order.visit(tree)
print order.identifiers

打印出所有类定义中赋值和方法的顺序。

演示:

>>> sourcecode = '''\
... class A(object):
...   b = 1
...   a = 1
...   c = 1
... '''
>>> tree = ast.parse(sourcecode)
>>> order = ClassOrder()
>>> order.visit(tree)
>>> print order.identifiers
['b', 'a', 'c']
>>> tree = ast.parse(inspect.getsource(ast.NodeVisitor))
>>> order = ClassOrder()
>>> order.visit(tree)
>>> print order.identifiers
['visit', 'generic_visit']

使用 inspect.getsource() 捆绑为函数:

import inspect

def get_identifiers(obj):
    source = inspect.getsource(obj)
    tree = ast.parse(source)
    order = ClassOrder()
    order.visit(tree)
    return order.identifiers

inspect.getsource() 可以处理任何源可用的对象。对于类,它将提取定义该类的源 block (如果可用)。

关于python - 如何使用反射或解析读取Python类中声明成员的顺序(禁止元类替换)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24340197/

相关文章:

python - 检查 python 中的超时错误

python - plt.plot 分类轴过度拥挤

python - Heroku 部署 - PermissionError : [Errno 13] Permission denied: '/etc/passwd-'

c++ - 错误 : variable '*' has initializer but incomplete type and one other

python - 为什么我的 setup.py 生成的脚本找不到我还安装的模块?

python - 是否有不包含任何库的可移植 Python 2.7 Windows 发行版?

python - 如何在 Django 中对模型进行两次过滤?

python - 在函数内使用 exec 设置变量

c# - 是否有任何扩展或方法可以像在 VS 中一样在 VS Code 中添加 C# 类?

Javascript - 如果语句不起作用?