为了账号安全,请及时绑定邮箱和手机立即绑定

理解_GET_和Python描述符

理解_GET_和Python描述符

湖上湖 2019-07-05 09:27:37
理解_GET_和Python描述符我是试着了解Python的描述符是什么以及它们可以用于什么。然而,我在这方面失败了。我明白它们是如何工作的,但这是我的疑虑。考虑以下代码: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 Temperature(object):     celsius = Celsius()为什么我需要描述符类?是什么instance和owner这里?(在__get__)。这些参数的目的是什么?我如何调用/使用这个例子?
查看完整描述

3 回答

?
蓝山帝景

TA贡献1843条经验 获得超7个赞

说明符是Python的property类型实现。描述符只是实现了__get____set__等等,然后添加到其定义中的另一个类中(就像上面对温度类所做的那样)。例如:

temp=Temperature()temp.celsius #calls celsius.__get__

访问分配给(celsius在上面的例子中)调用适当的描述符方法。

instance在……里面__get__是类的实例(因此,__get__会收到temp,同时owner是带有描述符的类(所以应该是Temperature).

您需要使用描述符类来封装驱动它的逻辑。这样,如果描述符被用来缓存一些昂贵的操作(例如),它可以将值存储在自身上,而不是它的类上。

可以找到一篇关于描述符的文章。这里.

编辑:正如jchl在评论中指出的,如果您只是尝试Temperature.celsiusinstance将是None


查看完整回答
反对 回复 2019-07-05
?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

为什么我需要描述符类?

它使您对属性的工作方式有了额外的控制。例如,如果您习惯于Java中的getter和setter,那么它就是Python的方法。一个优点是,在用户看来,它就像一个属性(语法没有变化)。因此,您可以从一个普通的属性开始,然后,当您需要做一些花哨的事情时,切换到一个描述符。

属性只是一个可变的值。描述符允许您在读取或设置(或删除)值时执行任意代码。因此,您可以想象使用它将属性映射到数据库中的字段,例如,一种ORM。

另一种用途可能是拒绝接受新值,方法是在__set__-有效地使“属性”只读。

是什么instanceowner这里?(在__get__)。这些参数的目的是什么?

这是相当微妙的(我在这里写一个新答案的原因-我在思考同样的问题时发现了这个问题,但没有找到那么好的现有答案)。

描述符是在类上定义的,但通常是从实例调用的。当从实例调用它时,两个instanceowner都设置好了(你可以算出owner从…instance所以这似乎是毫无意义的)。但是当从一个类调用时,只有owner是设定-这就是为什么它在那里。

这只需要__get__因为它是唯一可以在类上调用的。如果设置类值,则设置描述符本身。同样用于删除。这就是为什么owner那里不需要。

我如何调用/使用这个例子?

好吧,下面是一个使用类似类的很酷的技巧:

class Celsius:

    def __get__(self, instance, owner):
        return 5 * (instance.fahrenheit - 32) / 9

    def __set__(self, instance, value):
        instance.fahrenheit = 32 + 9 * value / 5class Temperature:

    celsius = Celsius()

    def __init__(self, initial_f):
        self.fahrenheit = initial_f


t = Temperature(212)print(t.celsius)t.celsius = 0print(t.fahrenheit)

(我使用Python 3;对于python 2,您需要确保这些分区是/ 5.0/ 9.0)。这意味着:

100.0
32.0

现在有其他更好的方法在python中实现同样的效果(例如,如果摄氏度是一个属性,这是相同的基本机制,但将所有的源都放在了温度类中),但这表明了可以做的事情.


查看完整回答
反对 回复 2019-07-05
  • 3 回答
  • 0 关注
  • 424 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信