【问题标题】:How to access Magic Methods inside a Class python如何访问类 python 中的魔术方法
【发布时间】:2018-03-17 19:48:11
【问题描述】:

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

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,其中__ 是魔术方法。那么如何打印__foodMagic 属性呢?

【问题讨论】:

  • 如果你想在类主体之外访问__food,那么不要使用前导下划线(前导下划线的主要目的是通过名称修改弱“隐藏”变量)。你会发现它是_Animal__food
  • @cᴏʟᴅsᴘᴇᴇᴅ,太好了。这就消除了疑问。所以_Animal也是一种神奇的方法?
  • 除非您想根据 self.__food 计算值,否则您甚至不应该费心定义getFood;让用户直接访问self.food即可。
  • 另外,“魔法方法”并不是一个定义完美的术语,但它通常用于像 __init____add__ 这样的方法——两边都有双下划线,而不仅仅是左边——让你的类符合 Python 或 stdlib 使用的“协议”。
  • 顺便说一句,双下划线实际上并不是为了向调用者隐藏变量,这样他们就不能故意使用它们,而是向子类隐藏它们,这样他们就不会意外使用它们。

标签: python python-2.7 class getter-setter


【解决方案1】:

添加前导下划线的主要目的是提供类似于 python 中的“私有变量”的东西。好吧,它们并不完全是私有变量——python 并没有真正提供这种语言特性。解释器将破坏名称,使得从类外部访问这些成员变得(稍微)困难。

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

由于类私有成员有一个有效的用例(即 避免名称与子类定义的名称发生名称冲突), 对这种机制的支持有限,称为名称修改。任何 __spam 形式的标识符(至少两个前导下划线,在 大多数尾随下划线)在文本上替换为 _classname__spam,其中 classname 是当前类名,去掉了前导下划线。这种修改是不加考虑的 到标识符的句法位置,只要它出现 在类的定义中。

总而言之,“私有”变量的错位版本,比如__x 将是_ClassName__x。您可以验证您的班级是否属于这种情况:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    • 2018-01-23
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    • 2010-11-08
    相关资源
    最近更新 更多