class a:
def __init__(self):
self._b()#why here use _b,not b,What's the difference
self._c='cccc'#why here use _c,not c,What's the difference
def _b():
print 'bbbb'
a.py
class a:
def __init__(self):
self._b()#why here use _b,not b,What's the difference
self._c='cccc'#why here use _c,not c,What's the difference
def _b(self):
开发者_Python百科 print 'bbbb'
b.py
from a import *
b=a()
b._b()
print b._c
it print bbbb bbbb bbbb bbbb cccc
Why can print out these, aren't _b and _c private variables.
Prefixing a variable or function name with an underscore is a convention in Python to indicate that the variable is private. From the docs:
Private” instance variables that cannot be accessed except from inside an object, don’t exist in Python. However, there is a convention that is followed by most Python code: a name prefixed with an underscore (e.g. _spam) should be treated as a non-public part of the API (whether it is a function, a method or a data member). It should be considered an implementation detail and subject to change without notice.
Per pep8 (http://www.python.org/dev/peps/pep-0008/), a single underscore is intended to denote a "generally private" method or attribute. The interpreter itself has no interaction with the single underscore, its more of a convention. The double underscore OTOH has significance within the interpreter.
Basically, the idea is that in Python convention, there are three levels of encapsulation/hiding.
Public attributes and methods: These are meant to be accessed by other classes without restriction.
Private attributes and methods (prefixed with an underscore): These are meant to be hidden from the outside world. The underscore serves as something like a warning to say: you shouldn't be touching this method unless you really know what you're doing. Primarily, this is used to differentiate between end users (the lesser mortals) and other developers.
There is a third level called mangled. Any attributes/methods that are mangled are basically not to be touched by anyone who is not the author of that code. It is important to the core functioning of the program and should not be touched, because if it is misused, then it may lead to unwanted/unplanned behavior.
In your case, the '_b' method is a private method. The author of this code wants to let you know that this is not meant for public use, rather if you are writing a wrapper around this class or something of that nature (basically if you are developer using this class), then you may use that method. Otherwise, it is better that you don't.
Also, a single underscore in front of a variable(or method) ties it to that class. So when a._b
is called, the interpreter looks for it in the definition of the class a
.
Difference between single and double underscore:
class Foo(object):
def regular_method(self):
print 'ok'
def _soft_private(self):
print 'ok'
def __mangled_private(self):
print 'ok'
f = Foo()
f.regular_method()
# prints ok
f._soft_private()
# print ok
f.__mangled_private()
# error! no such attribute. BUT:
f._Foo__mangled_private()
# prints ok
So in essence there is no real "privacy" in python, but convention of using single underscore to warn developer using your API that he's doing so at his own risk.
You'll notice that b
isn't defined anywhere. While _b
is.
Unless you're asking why that naming convention is being used, in which case, you should ask the author of that code.
The underscore is simply used to denote that the variable is private.
The class object a
has an attribute _b
which is found when asking for self._b
. The same class object a
has no attribute b
.
_b
and b
are as different as beehive
and zulu
.
You will get a parameter error when calling self._b
because Python will implicitly pass self
as the first argument to a bound method. The signature should be:
def _b(self):
print('bbbb')
精彩评论