An identifier occurring as an atom is a name.
Private name mangling
When an identifier that textually occurs in a class definition begins with two or more underscore characters and does not end in two or more underscores, it is considered a private name of that class. Private names are transformed to a longer form before code is generated for them. The transformation inserts the class name, with leading underscores removed and a single underscore inserted, in front of the name.
For example, the identifier__spam
occurring in a class namedHam
will be transformed to_Ham__spam
. This transformation is independent of the syntactical context in which the identifier is used.
!Note:
- If the transformed name is extremely long (longer than 255 characters), implementation defined truncation may happen.
- If the class name consists only of underscores, no transformation is done.
for example
- 1
class A(object):
def __init__(self):
self.__name = 'Apple'
>>> a = A()
>>> a.__name
...
AttributeError: 'A' object has no attribute '__name'
>>> a._A__name
Apple
- 2
class A(object):
def __init__(self):
self.__private()
self.public()
def __private(self):
print 'A.__private()'
def public(self):
print 'A.public()'
class B(A):
def __private(self):
print 'B.__private()'
def public(self):
print 'B.public()'
>>> b = B()
A.__private()
B.public()
- 3
class C(A):
def __init__(self):
self.__private()
self.public()
def __private(self):
print 'C.__private()'
def public(self):
print 'C.public()'
>>> c = C()
C.__private()
C.public()
- 4
>>> class A(object):
def __init__(self):
self._A__private()
self.public()
def __private(self):
print 'A.__private()'
def public(self):
print 'A.public()'
>>>a = A()
A.__private()
A.public()
- 5
class __(object):
def __init__(self):
self.__name = 'Noooo'
>>> a = __()
>>> a.__name
Noooo
- read more
从菜鸟到菜菜鸟 同学的 理解Python的双下划线命名
UnboundLocalError
When a name is not found at all, a NameError exception is raised. If the current scope is a function scope, and the name refers to a local variable that has not yet been bound to a value at the point where the name is used, an UnboundLocalError exception is raised. UnboundLocalError is a subclass of NameError.
for example
- 1
>>> x = 10
def bar():
print x
...
>>> bar()
10
- 2
>>> x = 10
def foo():
print x
x += 1
...
>>> foo()
...
UnboundLocalError: local variable 'x' referenced before assignment
This is because when you make an assignment to a variable in a scope, that variable becomes local to that scope and shadows any similarly named variable in the outer scope. Since the last statement in foo assigns a new value to x, the compiler recognizes it as a local variable. Consequently when the earlier print x attempts to print the uninitialized local variable and an error results.
- 3
>>> x = 10
def foobar():
global x
print x
x += 1
...
>>> foobar()
10
>>> x
11
If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global.
- read more
unboundlocalerror
free variable
If a variable is used in a code block but not defined there, it is a free variable.
>>> i = 10
def f():
print(i)
...
>>> i = 42
>>> f()
42
Name resolution of free variables occurs at runtime, not at compile time.
- read more
Naming and binding¶