如何访问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使用。顺便说一句,双下划线并不是对调用方隐藏变量,这样他们就不会有意使用变量,而是对子类隐藏变量,这样他们就不会意外使用变量。