首页 > 解决方案 > Python3:访问一个 dunder 变量

问题描述

我知道 Python dunder 变量是什么,而且我知道名称修饰。

但由于某种原因,我无法访问以下代码片段中的 dunder 变量:

    for node in ast.find_all((Call,)):
        # Check if the identifier match the extension name
        if node.node.identifier == 'myapp.ext.MyExtension':
            # I want to access node.__meta
            print("==> type(node) = %s" % type(nod))
            print("==> node.__dict__ = %s" % node.__dict__")

哪个打印:

==> type(node) = <class 'jinja2.nodes.Call'>
==> node.__dict__ = {
        'kwargs': [],
        # ... a bunch of other attributes
        # The __meta attribute below is what I want to access
        '__meta': {'type': 'checkbox', 'value': Const(value='checked'), 'name': Const(value='agree'), 'class': Const(value='bold')}
    }

由于该node变量是Call该类的一个实例,并且我想访问它的__meta属性,根据名称修饰,我必须这样做node._Call__meta,但我收到一个错误:

`'Call' object has no attribute '_Call__meta'`

我究竟做错了什么?

标签: pythonoop

解决方案


__dict__您似乎对名称修饰和交互方式有一点误解。__dict__条目不受名称修饰的影响 - 如果您在 中看到名称'__meta'__dict__则该属性按字面意思命名__meta(而不是_Call__meta)。

您可以通过这个小演示自己确认这一点:

class Demo:
    __meta = 5

print('__meta' in vars(Demo))  # False
print('_Demo__meta' in vars(Demo))  # True

有两种方法可以访问此__meta属性:

  1. 如果您的代码不在类中,则可以使用node.__meta. 这在课堂上不起作用,因为那样__meta会被命名。
  2. 或者,您可以直接从__dict__with中获取属性node.__dict__['__meta']

推荐阅读