我想了解内置函数属性是如何工作的。让我困惑的是,属性也可以用作装饰器,但它只在用作内置函数时接受参数,而在用作装饰器时不接受参数。
下面的例子来自文档:
class C:
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")
属性的参数是getx, setx, delx和一个doc字符串。
在下面的代码中,属性被用作装饰器。它的对象是x函数,但在上面的代码中,参数中没有对象函数的位置。
class C:
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
在本例中,如何创建x.setter和x.deleter装饰器?
在下面,我给出了一个例子来阐明@property
考虑一个名为Student的类,它有两个变量:name和class_number,并且希望class_number在1到5的范围内。
现在我将解释两个错误的解决方案,最后是正确的解决方案:
下面的代码是错误的,因为它没有验证class_number(在1到5的范围内)
class Student:
def __init__(self, name, class_number):
self.name = name
self.class_number = class_number
尽管经过验证,但这个解决方案也是错误的:
def validate_class_number(number):
if 1 <= number <= 5:
return number
else:
raise Exception("class number should be in the range of 1 to 5")
class Student:
def __init__(self, name, class_number):
self.name = name
self.class_number = validate_class_number(class_number)
因为class_number验证只在创建类实例时检查,在创建类实例后不检查(可以将class_number更改为1到5范围之外的数字):
student1 = Student("masoud",5)
student1.class_number = 7
正确的解决方法是:
class Student:
def __init__(self, name, class_number):
self.name = name
self.class_number = class_number
@property
def class_number(self):
return self._class_number
@class_number.setter
def class_number(self, class_number):
if not (1 <= class_number <= 5): raise Exception("class number should be in the range of 1 to 5")
self._class_number = class_number
这之后:
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
等于:
class C(object):
def __init__(self):
self._x = None
def _x_get(self):
return self._x
def _x_set(self, value):
self._x = value
def _x_del(self):
del self._x
x = property(_x_get, _x_set, _x_del,
"I'm the 'x' property.")
等于:
class C(object):
def __init__(self):
self._x = None
def _x_get(self):
return self._x
def _x_set(self, value):
self._x = value
def _x_del(self):
del self._x
x = property(_x_get, doc="I'm the 'x' property.")
x = x.setter(_x_set)
x = x.deleter(_x_del)
等于:
class C(object):
def __init__(self):
self._x = None
def _x_get(self):
return self._x
x = property(_x_get, doc="I'm the 'x' property.")
def _x_set(self, value):
self._x = value
x = x.setter(_x_set)
def _x_del(self):
del self._x
x = x.deleter(_x_del)
也就是:
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x