Python中的property是一种特殊的装饰器,它可以将函数转换为属性,即方法调用像属性一样使用。在Python中,属性和特性是一对密切相关的概念,因为它们共同构成了一个类的接口。
一、property的使用
1.1 基本用法
假设现在有一个名为Person的类,有属性name和age,我们需要对属性进行一些限制。下面是使用property实现对属性访问的过程:
class Person:
def __init__(self, name, age):
self._name = name
self._age = age
@property
def name(self):
return self._name
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not isinstance(value, int):
raise ValueError("age must be an integer")
if value <= 0 or value > 120:
raise ValueError("age must between 1 and 120")
self._age = value
p = Person("Bob", 20)
print(p.name) # output: Bob
print(p.age) # output: 20
p.age = 25 # set age
print(p.age) # output: 25
在上面的示例中,我们通过@property将name和age方法转换为属性。对于getter方法,我们直接使用@property进行装饰;对于setter方法,我们需要使用@xxx.setter装饰器,其中xxx表示属性名。
1.2 高级用法
除了基本用法之外,property还有一些高级用法,比如可以使用property实现只读属性,如果尝试设置只读属性,就会引发AttributeError异常。示例代码如下所示:
class Person:
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
@property
def age(self):
raise AttributeError("age is a read-only attribute")
p = Person("Bob")
print(p.name) # output: Bob
print(p.age) # output: AttributeError
p.age = 25 # set age, AttributeError
二、属性和特性之间的优先权
Python中的属性和特性之间存在着优先权,即如果类中既有属性又有特性,那么Python会根据以下规则来决定调用哪个:
- 如果属性的名字与特性的名字相同,那么属性拥有优先权,Python将访问该属性,而不是访问特性。
- 如果通过属性访问特性,那么特性也就拥有了优先权。
- 如果特性具有setter方法,那么通过属性访问特性是相当于调用该setter方法,即该特性也就成为属性成分的一部分,因此其优先权也是较高的。
以下是示例代码,用来说明属性和特性之间的优先权:
class DemoClass:
def __init__(self):
self._value = 1
@property
def value(self):
print("get value")
return self._value
@value.setter
def value(self, v):
print("set value=%s" % v)
self._value = v
def __getattr__(self, name):
print("__getattr__ %s" % name)
return "not found"
def __getattribute__(self, name):
print("__getattribute__ %s" % name)
return object.__getattribute__(self, name)
d = DemoClass()
print(d.value) # output: __getattribute__ value\nget value\n1
print(d.__dict__) # output: {'_value': 1}
d.value = 2 # output: __getattribute__ value\nset value=2
print(d.__dict__) # output: {'_value': 2}
print(d.x) # output: __getattribute__ x\n__getattr__ x\nnot found
从上面的示例可以看出,通过属性访问特性时,特性具有更高的优先权。此外,如果属性和特性的名字相同,则属性拥有更高的优先权。如果属性和特性都不存在,那么Python将调用对象的__getattr__方法。此外,属性和方法的优先级同样存在关系,如果属性和方法的名字相同,那么属性拥有更高的优先级。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python中的property及属性与特性之间的优先权 - Python技术站