Python 使我们能够在类中通过在名称前加上双下划线来创建 “私有” 方法和变量,如下所示: __myPrivateMethod()
。那么,如何解释这一点
>>> class MyClass:
... def myPublicMethod(self):
... print 'public method'
... def __myPrivateMethod(self):
... print 'this is private!!'
...
>>> obj = MyClass()
>>> obj.myPublicMethod()
public method
>>> obj.__myPrivateMethod()
Traceback (most recent call last):
File "", line 1, in
AttributeError: MyClass instance has no attribute '__myPrivateMethod'
>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']
>>> obj._MyClass__myPrivateMethod()
this is private!!
这是怎么回事?!
我会为那些不太了解的人解释一下。
>>> class MyClass:
... def myPublicMethod(self):
... print 'public method'
... def __myPrivateMethod(self):
... print 'this is private!!'
...
>>> obj = MyClass()
我在那里所做的是创建一个具有公共方法和私有方法的类,并将其实例化。
接下来,我将其称为 public 方法。
>>> obj.myPublicMethod()
public method
接下来,我尝试调用其私有方法。
>>> obj.__myPrivateMethod()
Traceback (most recent call last):
File "", line 1, in
AttributeError: MyClass instance has no attribute '__myPrivateMethod'
这里的一切看起来都不错。我们无法调用它。实际上,它是 “私有” 的。好吧,实际上不是。在对象上运行dir()会揭示一个新的神奇方法,python 会为您的所有 “私有” 方法神奇地创建该方法。
>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']
这个新方法的名称始终是一个下划线,其后是类名,然后是方法名。
>>> obj._MyClass__myPrivateMethod()
this is private!!
封装这么多,是吗?
无论如何,我总是会听到 Python 不支持封装,那为什么还要尝试呢?是什么赋予了?
名称加扰用于确保子类不会意外覆盖其超类的私有方法和属性。它的目的不是防止来自外部的故意访问。
例如:
>>> class Foo(object):
... def __init__(self):
... self.__baz = 42
... def foo(self):
... print self.__baz
...
>>> class Bar(Foo):
... def __init__(self):
... super(Bar, self).__init__()
... self.__baz = 21
... def bar(self):
... print self.__baz
...
>>> x = Bar()
>>> x.foo()
42
>>> x.bar()
21
>>> print x.__dict__
{'_Bar__baz': 21, '_Foo__baz': 42}
当然,如果两个不同的类具有相同的名称,则它会崩溃。
import re
import inspect
class MyClass :
def __init__(self) :
pass
def private_function ( self ) :
try :
function_call = inspect.stack()[1][4][0].strip()
# See if the function_call has "self." in the begining
matched = re.match( '^self\.', function_call )
if not matched :
print 'This is Private Function, Go Away'
return
except :
print 'This is Private Function, Go Away'
return
# This is the real Function, only accessible inside class #
print 'Hey, Welcome in to function'
def public_function ( self ) :
# i can call private function from inside the class
self.private_function()
### End ###
当我第一次从 Java 到 Python 时,我讨厌这一点。吓死我了。
今天,它可能只是我最喜欢 Python 的一件事。
我喜欢在一个平台上,人们可以互相信任,而不必觉得自己需要围绕自己的代码构建坚不可摧的墙。在高度封装的语言中,如果 API 有错误,并且您找出了问题所在,则可能仍无法解决它,因为所需的方法是私有的。在 Python 中,态度是:“确定”。如果您认为自己了解情况,也许您甚至已经读过它,那么我们所能说的就是 “祝您好运!”。
请记住,封装甚至与 “安全性” 或使孩子远离草坪的关系都不是很弱。这只是使代码库更易于理解的另一种模式。