python 属性、@property和属性描述符

python 属性

类属性和实例属性

在类中定义的是类属性,在实例中定义的是实例属性。
如下定义的属性是类属性:

class Person:
	name = None
Person.gender = 'man'

如下定义的属性是实例属性:

class Person:
	def __init__(self, tall = None):
		self.tall = tall
person = Person()
person.old = 12

@property装饰器

如果在设置类的某一个实例属性前需要验证,可以使用@property装饰器:

class Person:
	@property
	def name(self):
		retuen self._name
	@name.setter
	def setName(self, value):
		if name is None:
			raise ValueError("name should be None!")
		self._name = value
	@name.deleter
	def deleteName(self):
		del self._name

属性描述符

如果说有多个属性有相同的验证方式,可以定义一个类以提高代码利用率。这个类被称为描述符。描述符类需要实现__set__方法、__delete__方法、__get__方法或__set_name__方法,其中__set_name__方法是可选的。
属性描述符的用法为:

class NameValidator:
'''
假设这是一个属性描述符
'''

	...
class Person:
	name = NameValidator() #使用属性描述符创建name属性

alice = Person()
alice.name = "alice"

在类的定义中创建类属性,将其实例化为属性描述符,即对于该类声明了一个实例属性。对于类的实例中如果对该属性进行复制、获取和删除操作时都会访问属性描述符。

__set__方法

__set__方法用来设置属性。__set__方法含有两个参数:instancevalueinstance代表属性的持有者,value代表要设置的值。

class NameValidator:
	def __set__(self, instance, value):
		instance.__dict__['name] = value
class Person:
	name = NameValidator() 
alice = Person()
alice.name = "alice" # 调用__set__方法

__set_name__方法

__set_name__用于苗书旗获取属性的名称。__set_name__方法有两个参数:owner, nameowner指的是属性持有类的类对象,name指的是属性名称。__set_name__方法在属性持有类的初始化过程中会调用。

class NameValidator:
	def __set_name__(self, owner, name):
		self.property_name = name
class Person:
	name = NameValidator() # 在Person类的初始化过程中调用,owner为Person类对象,name为属性名字符串"name"

__get__方法

__get__方法用来获取属性值。__get__有两个参数,第一个参数instance代表实例对象,第二个参数代表实例对象的类对象。在访问类的实例对象的描述器定义的属性的会被调用。

class NameValidator:
	def __get__(self, instance, owner):
		instance.__dict__['name] = value
class Person:
	name = NameValidator() 
alice = Person()
alice.name = "alice" # 调用__set__方法
print(alice.name) # 调用__get__方法, instance 值为alice, owner值为Person

__delete__方法

__delete__方法在删除属性的时候会被调用。有一个参数代表实例对象。

class NameValidator:
	def __delete__(self, instance):
		idel nstance.__dict__['name']
class Person:
	name = NameValidator() 
del alice.name # __delete__方法会被调用,instance为alice

属性描述符分为两种:数据描述符和非数据描述符:

  • 数据描述符: 实现了__set__方法和/或__delete__方法;
  • 非数据描述符: 只实现了__get__方法。

不同的描述符访问属性的顺序不同。对于非数据描述符,python首先从实例的__dict__中查找属性,没有的话才会调用__get__方法;对于数据描述符,python则直接通过__get__方法获取属性。

参考链接:

  1. python descriptors
  2. python data descriptors
  3. Descriptor HowTo Guide
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值