簡體   English   中英

python屬性類實例如何工作?

[英]How does python property class instance work?

我有這個

#!/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                                  

這給出:

$ ./propertytest.py 
<property object at 0x7ff0426ac0a8> <type 'property'>
<property object at 0x7ff0426ac0a8> <type 'property'>
<property object at 0x7ff0426ac0a8> <type 'property'>

題:

查看訪問屬性對象area的方式: c.area area顯示在點運算符的右側。 屬性對象使用哪種特殊方法將類實例對象與正確的實例方法綁定在一起並計算結果? 物業如何運作?

屬性是描述符。 描述符是具有__get____set__和/或__delete__方法的類的實例。 每當python執行getattrsetattrdelattr ,如果實例不具有上述屬性,並且在類中具有該名稱的屬性,且具有匹配的magic方法,則將調用magic方法,而不是讀取/寫入/刪除屬性。

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__)

為了使上面發生的事情更加明確,讓我們擺脫裝飾器語法糖:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM