I know what double underscore means for Python class attributes/methods, but does it mean something for method argument?
It looks like you cannot pass argument starting with double underscore to methods. It is confusing because you can do that for normal functions.
Consider this script:
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)
Running this script yields:
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'
I checked this with Python 2.7.2.
Some other examples
This works:
def egg(self, __a):
return __a
class Spam(object):
egg = egg
Spam().egg(__a=1)
This does not:
class Spam(object):
def _egg(self, __a=None):
return __a
def egg(self, a):
return self._egg(__a=a)
Spam().egg(1)
Name mangling applies to all identifiers with leading double underscores, regardless of where they occur (second to last sentence in that section):
This is simpler to implement and to define, and more consistent. It may seem stupid, but the whole name mangling deal is an ugly little hack IMHO; and you’re not expected to use names like that for anything except attributes/methods anyway.
Spam().egg(_Spam__a=1), as well asSpam().egg(1), does work. But even though you can make it work, leading underscores (any number of them) have no place in parameter names. Or in any local variable (exception:_) for that matter.Edit: You appear to have found a corner case nobody ever considered. The documentation is imprecise here, or the implementation is flawed. It appears keyword argument names are not mangled. Look at the bytecode (Python 3.2):
This may be rooted in the fact that keyword arguments are equivalent to passing a dict (in this case
{'__a': 1}) whose keys wouldn’t be mangled either. But honestly, I’d just call it an ugly corner case in an already ugly special case and move on. It’s not important because you shouldn’t use identifiers like that anyway.