[英]How does python property class instance work?
I have this 我有这个
#!/usr/bin/env python
import math
class myclass(object):
def __init__(self,radius):
self.radius = radius
@property
def area(self):
print myclass.area, type(myclass.area)
return math.pi * ( self.radius ** 2)
@area.setter
def area(self,value):
print myclass.area, type(myclass.area)
pass
@area.deleter
def area(self):
print myclass.area, type(myclass.area)
del myclass.area
if __name__ == '__main__':
c = myclass(5.4)
c.area
c.area = 65
del c.area
This gives: 这给出:
$ ./propertytest.py
<property object at 0x7ff0426ac0a8> <type 'property'>
<property object at 0x7ff0426ac0a8> <type 'property'>
<property object at 0x7ff0426ac0a8> <type 'property'>
Question: 题:
Look at the way property object area
has been accessed: c.area
. 查看访问属性对象
area
的方式: c.area
。 area
appears on the right side of the dot operator. area
显示在点运算符的右侧。 Which special method is used by the property object to bind the class instance object with the right instance method and compute the result? 属性对象使用哪种特殊方法将类实例对象与正确的实例方法绑定在一起并计算结果? How do properties work?
物业如何运作?
Properties are descriptors. 属性是描述符。 A descriptor is an instance of a class with
__get__
, __set__
and/or __delete__
method. 描述符是具有
__get__
, __set__
和/或__delete__
方法的类的实例。 Whenever python does getattr
, setattr
and delattr
, if the instance does not have said attribute, and in the class there is a attribute with that name, that has the matching magic method, the magic method is called instead of the reading/writing/deleting the attribute. 每当python执行
getattr
, setattr
和delattr
,如果实例不具有上述属性,并且在类中具有该名称的属性,且具有匹配的magic方法,则将调用magic方法,而不是读取/写入/删除属性。
The Python documentation tells more on descriptors and also has this pure python emulation of builtin property
type: Python文档提供了有关描述符的更多信息,并且还具有以下内置
property
类型的纯python仿真:
class Property(object):
"Emulate PyProperty_Type() in Objects/descrobject.c"
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
if doc is None and fget is not None:
doc = fget.__doc__
self.__doc__ = doc
def __get__(self, obj, objtype=None):
if obj is None:
return self
if self.fget is None:
raise AttributeError("unreadable attribute")
return self.fget(obj)
def __set__(self, obj, value):
if self.fset is None:
raise AttributeError("can't set attribute")
self.fset(obj, value)
def __delete__(self, obj):
if self.fdel is None:
raise AttributeError("can't delete attribute")
self.fdel(obj)
def getter(self, fget):
return type(self)(fget, self.fset, self.fdel, self.__doc__)
def setter(self, fset):
return type(self)(self.fget, fset, self.fdel, self.__doc__)
def deleter(self, fdel):
return type(self)(self.fget, self.fset, fdel, self.__doc__)
To make what is happening above a bit more explicit, let's get rid of the decorator syntax sugar: 为了使上面发生的事情更加明确,让我们摆脱装饰器语法糖:
import math
class myclass(object):
def __init__(self,radius):
self.radius = radius
def getter(self):
print myclass.area, type(myclass.area)
return math.pi * ( self.radius ** 2)
# create a property object with "getter" as the getter, assigned to "area"
area = property(getter)
# area.__get__ is now a method that wraps "getter"
def setter(self,value):
print myclass.area, type(myclass.area)
pass
# create a copy of the "area" object with "setter" as a setter, assign back to "area"
area = area.setter(setter)
# area.__set__ is now a method that wraps "setter"
def deleter(self):
print myclass.area, type(myclass.area)
del myclass.area
# create a copy of the "area" object with "deleter" as a deleter, assign back to "area"
area = area.deleter(deleter)
# area.__delete__ is now a method that wraps "deleter"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.