简体   繁体   English

python属性类实例如何工作?

[英]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执行getattrsetattrdelattr ,如果实例不具有上述属性,并且在类中具有该名称的属性,且具有匹配的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.

相关问题 通过 Python 中的反射创建 class 实例不起作用 - Creation of a class instance by reflection in Python does not work 如何强制python类具有CLASS属性? (不是实例属性!!!) - How to force a python class to have a CLASS property? (not a INSTANCE property!!!) Property如何使用Itemgetter im Python? - How does Property work with Itemgetter im Python? @property 装饰器在 Python 中是如何工作的? - How does the @property decorator work in Python? 一个 class 属性不能使其成为继承 class 的实例? - A class property does not make it to the instance of the inheriting class? 如何检索Python类实例的属性的docstring? - How can I retrieve the docstring for a property of a Python class instance? 如何在初始化类python期间重写实例变量属性的行为 - How to override instance variable property behavior during initialize class python 如何将一个 class 的实例传递给另一个工作? - How does passing an instance of one class to another work? 为什么这在 Python 中有效? 创建一个实例,在该类中设置一个不存在的属性,然后通过该实例打印该属性 - Why does this work in Python? Creating a instance, setting a non existent attribute in that class, then printing that attribute through the instance 派生类参数如何在 Python 中工作? - How does derived class arguments work in Python?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM