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)

运行结果:






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