Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何访问python类中的神奇方法_Python_Python 2.7_Class_Getter Setter - Fatal编程技术网

如何访问python类中的神奇方法

如何访问python类中的神奇方法,python,python-2.7,class,getter-setter,Python,Python 2.7,Class,Getter Setter,我很难理解这一点。假设我们有这样一段代码 class Animal: def __init__(self, name, food): self.name = name self.__food = food def getFood(self): return self.__food 然后我们初始化它 >>> animal = {} >>&g

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

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")
现在,在访问属性时,它似乎不允许我访问
\uu 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'
>>动物[“狗”]名称
“生锈的”
>>>动物[狗]食物
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:Animal实例没有属性“\uu food”

为什么会失败呢。我们可以清楚地看到,我使用的是
self.\uu food=food
,其中
\uuu
是一种神奇的方法。那么如何打印
\u food
Magic属性呢?

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

您可以阅读更多关于(2.x文档,因为您的问题被标记为这样)。相关摘录-

因为类私有成员有一个有效的用例(即 避免名称与子类定义的名称发生名称冲突) 对这种机制的支持是有限的,称为名称混乱。任何 垃圾邮件格式的标识符(至少两个前导下划线,至少 大多数尾随下划线)在文本上替换为
\u classname\uu spam
,其中classname是当前类名,去掉前导下划线。这种弄脏是不加考虑的 标识符的语法位置,只要它出现 在类的定义中

总之,“private”变量的损坏版本,比如
\uuux
将是
\uclassname\uuux
。您可以验证您的类是否存在这种情况:

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

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

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

您可以阅读更多关于(2.x文档,因为您的问题被标记为这样)。相关摘录-

因为类私有成员有一个有效的用例(即 避免名称与子类定义的名称发生名称冲突) 对这种机制的支持是有限的,称为名称混乱。任何 垃圾邮件格式的标识符(至少两个前导下划线,至少 大多数尾随下划线)在文本上替换为
\u classname\uu spam
,其中classname是当前类名,去掉前导下划线。这种弄脏是不加考虑的 标识符的语法位置,只要它出现 在类的定义中

总之,“private”变量的损坏版本,比如
\uuux
将是
\uclassname\uuux
。您可以验证您的类是否存在这种情况:

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

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

如果要在类主体之外访问
\uuu food
,则不要使用前导下划线(前导下划线的主要目的是通过名称扭曲来弱“隐藏”变量)。你会发现它是
\u Animal\u food
@cᴏʟᴅsᴘᴇᴇᴅ , 伟大的这澄清了疑问。所以
\u Animal
也是一个神奇的方法吗?除非你想根据
self.\uu food
计算一个值,你甚至不应该费心定义
获取食物
;只需让用户直接访问self.food。此外,“magic method”不是一个定义很好的术语,但它通常用于
\uuuuuuu init\uuuuuu
\uuuu add\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
等方法,两边都有双下划线,而不仅仅是左边的下划线由Python或stdlib使用。顺便说一句,双下划线并不是对调用者隐藏变量,这样调用者就不会有意使用它们,而是对子类隐藏变量,这样子类就不会意外使用它们。如果你想访问类主体之外的
\u food
,那么就不要使用前导下划线(前导下划线的主要目的是通过名称扭曲来弱“隐藏”变量)。你会发现它是
\u Animal\u food
@cᴏʟᴅsᴘᴇᴇᴅ , 很好。这就消除了疑问。那么
\u Animal
也是一种神奇的方法吗?除非你想根据
self.\u food
计算一个值,你甚至不应该费心定义
getFood
;只要让用户直接访问
self.food
。还有,“神奇方法”不是一个定义得很好的术语,但它通常用于
\uuuuu init\uuuuuu
\uuuuu add\uuuuuuu
之类的方法-两边都有双下划线,而不仅仅是左边的下划线,这样类就可以遵守“协议”由Python或stdlib使用。顺便说一句,双下划线并不是对调用方隐藏变量,这样他们就不会有意使用变量,而是对子类隐藏变量,这样他们就不会意外使用变量。