Python descriptor vs property [duplicate]

爷,独闯天下 提交于 2019-12-02 22:30:50

You should read the docs on what descriptors actually are. The Cliff's Notes version: descriptors are a low-level mechanism that lets you hook into an object's attributes being accessed. Properties are a high-level application of this; that is, properties are implemented using descriptors. Or, better yet, properties are descriptors that are already provided for you in the standard library.

If you need a simple way to return a computed value from an attribute read, or to call a function on an attribute write, use the @property decorator. The descriptor API is more flexible, but less convenient, and arguably "overkill" and non-idiomatic in this situation. It's useful for more advanced use cases, like implementing bound methods, or static and class methods; when you need to know, for example, if the attribute was accessed through the type object, or an instance of the type.

You can read more about both from here. But here's a simple example from the same book that tries to explain the differnce solving what essentialy is the same problem. As you can see, the implementation using properties is much simpler.

There are several ways that we can tap into Python's internal mechanisms for getting and setting attribute values. The most accessible technique is to use the property function to define get, set and delete methods associated with an attribute name. The property function builds descriptors for you. A slightly less accessible, but more extensible and reusable technique is to define descriptor classes yourself. This allows you considerable flexibility. You do this by creating a class which defines get, set and delete methods, and you associate your descriptor class with an attribute name.

The property function gives us a handy way to implement a simple descriptor without defining a separate class. Rather than create a complete class definition, we can write getter and setter method functions, and then bind these functions to an attribute name.

Descriptor example:

class Celsius( object ):
    def __init__( self, value=0.0 ):
        self.value= float(value)
    def __get__( self, instance, owner ):
        return self.value
    def __set__( self, instance, value ):
        self.value= float(value)

class Farenheit( object ):
    def __get__( self, instance, owner ):
        return instance.celsius * 9 / 5 + 32
    def __set__( self, instance, value ):
        instance.celsius= (float(value)-32) * 5 / 9

class Temperature( object ):
    celsius= Celsius()
    farenheit= Farenheit()
>>>
oven= Temperature()
>>>
oven.farenheit= 450
>>>
oven.celsius
232.22222222222223
>>>
oven.celsius= 175
>>>
oven.farenheit
347.0

Property example:

class Temperature( object ):
    def fget( self ):
        return self.celsius * 9 / 5 + 32
    def fset( self, value ):
        self.celsius= (float(value)-32) * 5 / 9
    farenheit= property( fget, fset )
    def cset( self, value ):
        self.cTemp= float(value)
    def cget( self ):
        return self.cTemp
    celsius= property( cget, cset, doc="Celsius temperature" )
>>>
oven= Temperature()
>>>
oven.farenheit= 450
>>>
oven.celsius
232.22222222222223
>>>
oven.celsius= 175
>>>
oven.farenheit
347.0
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!