python對象的私有封裝

python的實例很是靈活,在某些狀況下,若是想實現隱藏和封裝性時就須要一些小操做來提升python的準確性.python

_attr真不靠譜

_屬性只是提供模塊級別的隱藏,定義_屬性,在實例中,仍然能夠隨意操做。

 

三個辦法變得靠譜

# 1.藏. 私有屬性 __name , 達到隱藏的效果,但並不能保證屬性被意外染指
# 2.護 property函數 ,達到封裝性,只有顯示操做才能達到效果
# 3.限 __slot__ : 給python實例這個野孩子加緊箍咒, 禁止隨意添加屬性ssh

# -*-coding:utf-8 -*-

"""
 @author: 回憶書籤
 @version: 0.1
 @date:  2010-06-16
 @description:   python類中屬性的私有封裝
"""


class A(object):

	def __init__(self,name):
		self.__name=name  # 第一招 :私有屬性
		self.abc=123

	@property
	def name(self):
	# 第二招, 公有方法name獲得__name,在外界看name是一個屬性,而實際上name是一個函數的返回值.
        # 而函數的輸出是不能直接改變的,除非直接修改__name,而第一個辦法已經把__name藏起來了。.
		return self.__name

	@name.setter
	def setName(self,value):
	#共用方法setName,這裏沒有命名爲name,是故意讓使用者意識到本身在作什麼。
	#想要改變__name只有經過這個入口
		if not isinstance(value,str):
			raise TypeError('must be a string')
		self.__name=value

	@name.deleter
	def delName(self):
		del self.__name

	__slots__ = ('__name','abc') 
        #第三招限制實例屬性,將牆內的屬性都規定好,之後再想擠進來屬性就只能到這裏來定義

 

#實例化看看

if __name__ == "__main__":
	a=A('abc')
	print a.name
	a.setName='xyz'
	print a.name
        a.abc=4567

 #若是還想增長几個打醬油的進來,想也別想

a.dajiangyou=456

Traceback (most recent call last):
a.dajiangyou=456  AttributeError: 'A' object has no attribute 'dajiangyou'

#這個__name是動態加的李鬼,有了slot,李鬼馬上現形了。

a.__name='yyy'

Traceback (most recent call last):
File "encloseattr.py", line 48, in <module> # a.__name='yyy'
AttributeError: 'A' object has no attribute '__name'

#   牆內衆生真面目: 誰是公有的誰是私有的一看便知道

print dir(a)
	#  牆內衆生真面目: 誰是公有的誰是私有的一看便知道
	# ['_A__name',
	# '__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__',
	# '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__',
	# '__subclasshook__',
	# 'abc',  #公有屬性,沒有任何修飾
	# 'delName',
	# 'name',  #公有的getter
	# 'setName' #公有的setter
相關文章
相關標籤/搜索