Python property函數的用法

在Python中定義一個對象,在對對象中的屬性進行賦值時,可以直接選擇賦值,但這樣無法進行一些條件和規則的過濾,如定義一個長方體類,則它的寬和高也可以被賦值成字符串類型,顯然這是不符合要求的,因此我們可以通過定義訪問器方法來對賦值的變量進行檢查,但是如果屬性聲明和定義的過多的話,則在外部將要使用太多的訪問器方法,比如長度屬性,會有設置長度和獲取長度,寬也有設置寬度和獲取寬度。Python通過property函數,來簡化訪問器方法的使用。

property函數有四個屬性,分別是: fget, fset, fdel, doc, 分別對應取值方法,設置值方法和刪除特性以及文檔字符串。fdel和fdoc爲可選類型。

代碼如下:

class Rectangle(object):
	def __init__(self):
		self.width = 0
		self.height = 0
	def setSize(self, size):
		self.width, self.height = size
	def getSize(self):
		return self.width, self.height
	def delSize(self):
		del (self.width, self.height)
	size = property(getSize, setSize, delSize, 'This is a property example.')

注意,在Python2.7中需要使用新式類,在類的定義之前加上__metaclass__ = type或者讓類繼承自object,在Python3.6中測試可以直接使用。

運行結果

對於在舊式類中,可以使用__getattr__(self, name), __setattr__(self, name, value)以及__delattr__(self, name), 分別適用於當特性name被訪問時且對象沒有相應的特性時被自動調用,當試圖給特性name賦值時會被自動調用以及當試圖刪除特性name時被自動調用。

class Rectangle:
	def __init__(self):
		self.width = 0
		self.height = 0
	def __setattr__(self, name, value):
		if name == 'size':
			self.width, self.height = value
		else:
			self.__dict__[name] = value
	def __getattr__(self, name):
		if name == 'size':
			return self.width, self.height
		else:
			raise AttributeError
	def __delattr__(self, name):
		if name == 'size':
			del self.__dict__['width']
			del self.__dict__['height']
		else:
			if name in self.__dict__:
				del self.__dict__[name]
			else:
				raise KeyError

注意__dict__方法包含一個字典,字典裏是所有實例的屬性, __getattr__ 只有在訪問不存在的成員時纔會被調用。如果類型繼承自 object,可以使用__getattribute__ 來攔截所有(包括不存在的成員)的獲取操作, 其也可以攔截對__dict__的訪問,因此__getattribute__ 中不要使用 “return self.__dict__[name]” 來返回結果,因爲在訪問 “self.__dict__” 時同樣會被 __getattribute__ 攔截,從而造成無限遞歸形成死循環。

訪問__getattribute__中與self相關的特性,可以使用超類的__getattribute__(使用super函數)來獲取操作。

代碼如下:

class A(object):
	def __getattribute__(self, name):
		return object.__getattribute__(self, name)

運行結果:






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章