Python学习之路(17)——私有机制

在很多教材中,Python在面向对象编程(OOP)中都会介绍到Python的私有方法和私有属性。

以下划线开头的变量/方法:

1)_xxx        以“单下划线”开始的成员变量叫做保护变量,意思是只有类对象(即类实例)和子类读写才能访问这些变量,需要通过类提供的接口进行访问,不能用"from module import *"的方法导入

2)__xxx      类中的私有变量/方法,以“双下划线”开始的是私有成员,意思是只有类对象自己能访问,子类对象也无法访问该成员

3)__xxx__  系统定义名字,以“双下划线”开头和结尾的,代表Python李特殊方法的标识,比如__init__()代表类的构造函数。

举例:

>>> class Person():
	def __init__(self):
		self.__name = 'nicolas'      #私有属性
		self.age = 999
	def __get_name(self):               #私有方法
		return self.__name
	def get_age(self):
		return self.age

	
>>> person = Person()
>>> print(person.__name)
Traceback (most recent call last):
  File "<pyshell#46>", line 1, in <module>
    print(person.__name)
AttributeError: 'Person' object has no attribute '__name'
>>> print(person.__get_name())
Traceback (most recent call last):
  File "<pyshell#47>", line 1, in <module>
    print(person.__get_name())
AttributeError: 'Person' object has no attribute '__get_name'
>>> print(person.get_age())
999
>>>     

   

上面定义了一个类的私有属性"__name"和一个私有方法"__get_name()",如果直接用person.__name、person.__get_name()访问,就会抛出异常,提示对象没有该属性(对于Python来说,方法也是属性)。

 

但是,实际上,Python并没有真正的私有。在其内部实现上,是将私有变量进行了转化,实际上是_<类名><私有变量名>。比如,上面的私有变量如果想访问,可以使用_Person__name、_Person__get_name(),如下:

>>> print(person._Person__name)
nicolas
>>> print(person._Person__get_name())
nicolas
>>> 

  

我们通过dir()函数列举类属性和其实例属性的区别:

>>> dir(Person)
['_Person__get_name', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'get_age']
>>> 
>>> dir(person)
['_Person__get_name', '_Person__name', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'get_age']
>>> 

  

posted on 2018-03-03 20:15  nicolas_Z  阅读(165)  评论(0)    收藏  举报

导航