Python中魔法方法:描述符的个人理解

解析Python描述符机制,通过实例说明摄氏度与华氏度自动转换的实现过程,深入理解__get__和__set__魔法方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对小甲鱼的046魔法方法: 描述符课程中的例子的解析(个人笔记)

先看例子

class Descriptor_Centigrade:    #定义描述符类1,摄氏度描述符
    def __init__(self, value = 26.0):
        self.value = float(value)
                               
    def __get__(self, instance, owner):          
        return self.value
    
    def __set__(self, instance, value):
        self.value = float(value)
        
class Descriptor_Fahrenheit:    #定义描述符类2,华氏度描述符

    def __get__(self, instance, owner):
        return instance.c * 1.8 + 32
    
    def __set__(self, instance, value):
        instance.c = (float(value) - 32) / 1.8
        
class Temperature:    #定义温度类
    c = Descriptor_Centigrade()
    f = Descriptor_Fahrenheit()

该段代码定义了两种描述符,又定义了一个温度类,实现了摄氏度华氏度的自动转换并打印转换结果这样一个简单的功能。
效果如下:

In [2]: t = Temperature()   #实例化温度类的对象

In [3]: t.c
Out[3]: 26.0

In [4]: t.f
Out[4]: 78.80000000000001

In [5]: t.c = 50

In [6]: t.f
Out[6]: 122.0

In [7]: t.f = 100

In [8]: t.c
Out[8]: 37.77777777777778

首先,以魔法方法__get__为例,解释一下其内部参数:

__get__(self, instance, owner),查看行为发生时自动执行。其中:
self也就是该描述符类的实例对象自己,上例中为c
instance表示类(上例温度类,非描述符类)的实例对象,例如t = Temperature,那么这个t就是instance
owner就表示Temperature这个类。

而魔法方法__set__:
__set__(self, instance, value)
也是一样,不同的value代表赋值行为发生时,如上例t.c = 50,等号右端的值50

弄懂了这两个魔法方法,下面开始解析流程:

首先,t = Temperature创建一个温度类的实例化对象;
然后,执行t.c,会创建描述符类1(摄氏度描述符类)的实例对象(即c = Descriptor_Centigrade()),并自动赋初值
value = 26.0,又由这个t.c查看行为自动触发__get__方法,可看作__get__(c, t, Temperature),返回self.value,即Out[3]: 26.0
接着,执行t.f,同样在创建描述符类2(华氏度描述符类)的实例对象(即f = Descriptor_Fahrenheit())同时触发
__get__方法,
返回instance.c * 1.8 + 32也就是t.c * 1.8 + 32,即Out[4]: 78.80000000000001

继续,当赋值行为发生时,自动调用__set__方法;
输入In [5]: t.c = 50,自动调用描述符类1的__set__方法,执行self.value = float(value)50.0重新赋给t.c
输入In [6]: t.f,自动调用描述符类2的__set__方法,执行return instance.c * 1.8 + 32返回新的计算值,即
Out[6]: 122.0

相反,当先赋值给t.f时:
In [7]: t.f = 100,会自动调用描述符类2的__set__方法,执行instance.c = (float(value) - 32) / 1.8,将t.c改写成新值37.77777777777778,故此时调用In [8]: t.c,会显示Out[8]: 37.77777777777778
至此结束。

对各个参数的简单解释也写在了代码片上,如下:

class Descriptor_Centigrade:
    def __init__(self, value = 26.0):
        self.value = float(value)

#魔法方法__get__(self, instance, owner)参数的解释:
        
        
#                               instance:类的实例对象(比如 t=Temperature, 那么这个 t 就是 instance)
#                                      ↗                                                                                          
# self:描述符的实例对象 ( c )        ↗        owner:类,也就是 Temperature
#                  ↑             ↗       ↗                                               
#                  ↑          ↗      ↗                               
    def __get__(self, instance, owner):          
        return self.value
    
    def __set__(self, instance, value):
        self.value = float(value)
    
class Descriptor_Fahrenheit:

    def __get__(self, instance, owner):
        return instance.c * 1.8 + 32
    
    def __set__(self, instance, value):
        instance.c = (float(value) - 32) / 1.8
    
class Temperature:
    c = Descriptor_Centigrade()
    f = Descriptor_Fahrenheit()
        
    
#使用时,实例化时:        
#            t = Temperature()         t:类的实例对象

#            c = Descriptor_Centigrade()   c:描述符1的实例对象
#            f = Descriptor_Fahernhiet()   f:描述符2的实例对象  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值