Python描述符vs属性

2024-04-28 21:51:30 发布

您现在位置:Python中文网/ 问答频道 /正文

Possible Duplicate:
When and why might I assign an instance of a descriptor class to a class attribute in Python rather than use a property?

我对何时使用属性和描述符感到困惑。我读到属性是一个特殊的描述符。

有人能发布一下这是怎么工作的吗?


Tags: andoftoinstancean属性描述符class
2条回答

您应该阅读文档中关于描述符的实际内容。Cliff的Notes版本:描述符是一种低级机制,允许您钩住正在访问的对象的属性。属性是这方面的高级应用程序;也就是说,属性是使用描述符实现的。或者,更好的是,属性是标准库中已经提供给您的描述符。

如果需要从属性读取返回计算值或在属性写入时调用函数的简单方法,请使用@property装饰符。描述符API更灵活,但不太方便,在这种情况下可以说是“过度杀戮”和非习惯用法。它对于更高级的用例很有用,比如实现绑定方法,或者静态和类方法;当您需要知道属性是通过类型对象还是通过类型的实例访问的时候。

您可以从here中阅读更多关于这两者的信息。但这是同一本书中的一个简单例子,它试图解释解决本质上是同一个问题的不同之处。如您所见,使用属性的实现要简单得多。

有几种方法可以利用Python的内部机制来获取和设置属性值。最易访问的技术是使用property函数定义与属性名关联的get、set和delete方法。property函数为您构建描述符。一种稍微不易访问,但更具可扩展性和可重用性的技术是自己定义描述符类。这允许你有相当大的灵活性。通过创建一个定义get、set和delete方法的类,并将描述符类与一个属性名相关联,就可以做到这一点。

property函数为我们提供了一种简便的方法来实现一个简单的描述符,而无需定义单独的类。而不是创建一个完整的类定义, 我们可以编写getter和setter方法函数,然后将这些函数绑定到属性名。

描述符示例:

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

属性示例:

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

相关问题 更多 >