【发布时间】:2022-01-25 13:25:14
【问题描述】:
所以我遇到了一个非常有趣的 python 名称修改行为。 考虑以下代码
class C:
def __init__(self):
self.__c = 1
@staticmethod
def change(instance):
print(dir(instance))
print(instance.__c)
print(instance._C__c)
在这里,我创建了一个私有字段 __c 并希望可以从类内直接访问它,并从类外通过 _C__c 访问它。因此,如果我们将 C 的实例传递给 C.change,第二次或第三次打印都应该失败。
让我们检查一下:
>>> c = C()
>>> dir(c)
['_C__c', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'change']
>>> C.change(c)
['_C__c', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'change']
1
1
首先,为了调试,我们使用dir(c) 打印c 的所有可用成员。然后我们调用 C.change 将变量 c 传递给它。
嗯,出乎意料,没有错误。
因此,change 中的第一次打印向我们展示了 instance 对象的所有可用条目。在这里,我们看到 __c 字段可用作 _C__c。这似乎没问题,因为我们不是通过自我访问,而是通过另一个变量。
从 'dir' 得到这样的输出,我希望 print(instance.__c) 会因 AttributeError 而失败。
然而,出乎意料的是,它工作得很好!
这真的让我很困惑,因为我不明白,为什么__c 可以访问,如果设计如此,那么为什么它没有在dir 输出中列出?
【问题讨论】:
标签: python python-3.x private member name-mangling