Why are Python's 'private' methods not actually private?
Python gives us the ability to create 'private' methods and variables within a class by prepending double underscores to the name, like this: __myPrivateMethod()
. How, then, can one explain this
>>> 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!!
What's the deal?!
I'll explain this a little for those who didn't quite get that.
>>> class MyClass:
... def myPublicMethod(self):
... print 'public method'
... def __myPrivateMethod(self):
... print 'this is private!!'
...
>>> obj = MyClass()
What I did there is create a class with a public method and a private method and instantiate it.
Next, I call its public method.
>>> obj.myPublicMethod()
public method
Next, I try and call its private method.
>>> obj.__myPrivateMethod()
Traceback (most recent call last):
File "", line 1, in
AttributeError: MyClass instance has no attribute '__myPrivateMethod'
Everything looks good here; we're unable to call it. It is, in fact, 'private'. Well, actually it isn't. Running dir() on the object reveals a new magical method that python creates magically for all of your 'private' methods.
>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']
This new method's name is always an underscore, followed by the class name, followed by the method name.
>>> obj._MyClass__myPrivateMethod()
this is private!!
So much for encapsulation, eh?
In any case, I'd always heard Python doesn't support encapsulation, so why even try? What gives?
The name scrambling is used to ensure that subclasses don't accidentally override the private methods and attributes of their superclasses. It's not designed to prevent deliberate access from outside.
For example:
>>> 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}
Of course, it breaks down if two different classes have the same name.
私人功能的例子
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 ###
From http://www.faqs.org/docs/diveintopython/fileinfo_private.html
Strictly speaking, private methods are accessible outside their class, just not easily accessible. Nothing in Python is truly private; internally, the names of private methods and attributes are mangled and unmangled on the fly to make them seem inaccessible by their given names. You can access the __parse method of the MP3FileInfo class by the name _MP3FileInfo__parse. Acknowledge that this is interesting, then promise to never, ever do it in real code. Private methods are private for a reason, but like many other things in Python, their privateness is ultimately a matter of convention, not force.
链接地址: http://www.djcxy.com/p/13782.html