我知道双下划线对于 Python 类属性/方法意味着什么,但是它对于方法参数意味着什么吗?
看起来您无法将以双下划线开头的参数传递给方法。这很令人困惑,因为您可以对正常功能执行此操作。
考虑这个脚本:
def egg(__a=None):
return __a
print "egg(1) =",
print egg(1)
print
class Spam(object):
def egg(self, __a=None):
return __a
print "Spam().egg(__a=1) =",
print Spam().egg(__a=1)
运行此脚本会产生:
egg(1) = 1
Spam().egg(__a=1) =
Traceback (most recent call last):
File "/....py", line 15, in <module>
print Spam().egg(__a=1)
TypeError: egg() got an unexpected keyword argument '__a'
我用 Python 2.7.2 检查了这一点。
其他一些例子
这有效:
def egg(self, __a):
return __a
class Spam(object):
egg = egg
Spam().egg(__a=1)
这不会:
class Spam(object):
def _egg(self, __a=None):
return __a
def egg(self, a):
return self._egg(__a=a)
Spam().egg(1)
名称修改适用于所有带前导双下划线的标识符,无论它们发生在哪里 http://docs.python.org/reference/expressions.html#atom-identifiers(该节倒数第二句):
此转换独立于使用标识符的语法上下文。
这更容易实现和定义,并且更加一致。这可能看起来很愚蠢,但恕我直言,整个名称修改交易是一个丑陋的小黑客;无论如何,您不应该对除属性/方法之外的任何内容使用这样的名称。
Spam().egg(_Spam__a=1)
, 也Spam().egg(1)
,确实有效。但即使您可以使其工作,前导下划线(任意数量)在参数名称中也没有位置。或者在任何局部变量中(例外:_
) 对于这个问题。
Edit:您似乎发现了一个从未有人考虑过的极端情况。这里的文档不精确,或者实现有缺陷。看来关键字参数名称没有被破坏。查看字节码(Python 3.2):
>>> dis.dis(Spam.egg)
3 0 LOAD_FAST 0 (self)
3 LOAD_ATTR 0 (_egg)
6 LOAD_CONST 1 ('__a') # keyword argument not mangled
9 LOAD_FAST 1 (a)
12 CALL_FUNCTION 256
15 RETURN_VALUE
>>> dis.dis(Spam._egg)
2 0 LOAD_FAST 1 (_Spam__a) # parameter mangled
3 RETURN_VALUE
这可能源于这样一个事实:关键字参数相当于传递一个字典(在本例中{'__a': 1}
)其钥匙也不会被损坏。但老实说,我只是将其称为已经丑陋的特殊情况中的丑陋的角落案例,然后继续前进。这并不重要,因为无论如何您都不应该使用这样的标识符。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)