为什么Python的“私有”方法实际上不是私有的?

Python使我们能够在类中创建'private'方法和变量,方法是在名称前加双下划线,如下所示: __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()

我在那里做的是创建一个具有公共方法和私有方法的类并实例化它。

接下来,我将其称为公共方法。

>>> 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 ###

从http://www.faqs.org/docs/diveintopython/fileinfo_private.html

严格来说,私人方法可以在课外访问,但不便于访问。 Python中没有什么是真正的私有的; 在内部,私有方法和属性的名称在运行时会被破坏和解除,使它们看起来无法通过它们的名称访问。 您可以通过名称_MP3FileInfo__parse访问MP3FileInfo类的__parse方法。 承认这很有趣,然后承诺永远不要以真实的代码去做。 私有方法由于某种原因是私有的,但与Python中的许多其他方面一样,它们的私有性最终只是约定的问题,而不是强制。

链接地址: http://www.djcxy.com/p/13781.html

上一篇: Why are Python's 'private' methods not actually private?

下一篇: Why do we actually need Private or Protected inheritance in C++?