如何在 Class python 中访问魔术方法

How to access Magic Methods inside a Class python

我很难理解这一点。假设我们有这样一段代码

class Animal:
        def __init__(self, name, food):
                self.name = name
                self.__food = food
        def getFood(self):
                return self.__food

然后我们初始化它

>>> animal = {}
>>> animal["dog"] = Animal("rusty", "delicious thing you never know")

现在访问属性的时候好像不让我访问__food

>>> animal["dog"].name
'rusty'
>>> animal["dog"].__food
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: Animal instance has no attribute '__food'

为什么会失败。我们可以清楚地看到我正在使用 self.__food = food,其中 __ 是魔术方法。那么如何打印 __food 魔法属性?

添加前导下划线的主要目的是提供类似于 python 中的 "private variables" 的内容。好吧,它们不完全是私有变量 - python 并没有真正提供这种语言功能。解释器会破坏名称,使从 class.

外部访问这些成员变得(稍微)困难

您可以在 official documentation 上阅读更多内容(2.x 文档,因为您的问题已被标记为此类)。相关摘录-

Since there is a valid use-case for class-private members (namely to avoid name clashes of names with names defined by subclasses), there is limited support for such a mechanism, called name mangling. Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class.

总而言之,"private" 变量的损坏版本,比如 __x 将是 _ClassName__x。您可以验证您的 class 是否属于这种情况:

In [251]: animal['dog']._Animal__food
Out[251]: 'delicious thing you never know'

是的,所以,正如我在评论中提到的,"private member" 的目的是使其不能在 class 之外访问。如果您定义此成员的目的是为了在外部访问它,那么您甚至不应该添加前导下划线。