欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python property函数的用法

程序员文章站 2022-06-08 15:44:54
...

在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中测试可以直接使用。

运行结果

>>> r = Rectangle()
>>> r.width = 10
>>> r.height = 10
>>> r.size
(10, 10)
>>> r.size = 1920, 1080
>>> r.height
1080
>>> r.width
1920
>>> del r.size
>>> r.width
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Rectangle' object has no attribute 'width'

对于在旧式类中,可以使用__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)

运行结果:

>>> a = A()
>>> a.f = 1
>>> a.f
1

原文:https://blog.csdn.net/mafengwoxiaozi8/article/details/79293907

相关标签: property