鱼C论坛

 找回密码
 立即注册
查看: 1620|回复: 3

[已解决]关于对象描述符问题

[复制链接]
发表于 2021-8-15 17:10:30 | 显示全部楼层 |阅读模式
10鱼币
class MyDes:
    def __init__(self,number,writ):
        self.number = number
        self.writ = writ

    def __get__(self, instance, owner):
        print('现在获取变量%s' %self.writ)
        return self.number

    def __set__(self, instance, value):
        print('变量%s在修改' %self.writ)
        self.number = value

    def __delete__(self, instance):
        print('正在山删除%s'%self.writ)
        print('变量:x删不了。')
class Test:
    x = MyDes(10,'x')

test = Test()


上面代码正常运行后,正常调用x,何修改x。
>>> test.x
现在获取变量x
10
>>> test.x = 1
变量x在修改

但我有想法,能不嫩创建个变量y能,然后实现上面变量x一样的功能。
>>> test.y = MyDes(4,'y')
>>> test.y
<__main__.MyDes object at 0x0000020C3CC3B848>
>>> test.y = 23
>>> test.y
23
>>> 

1、为什么会失败?原因在哪?
2、我这想法能实现吗?
最佳答案
2021-8-15 17:10:31

1、为什么会失败?原因在哪?


因为描述符只有作用在 类 层面上,Python 才会自动调用描述符的 __get__ 和 __set__

而此时你的 test 是 Test 类的实例对象,那么 test.y = MyDes(4, 'y') 实际上是在创建一个 实例属性,即类中带 self.变量名 的属性,而不是类层面上的属性

2、我这想法能实现吗?


可以实现,你只需将赋值过程用实例对象改成用类本身即可,如下代码:
Test.y = MyDes(4,'y')

即可成功创建了描述符,此时你在对实例进行 test.y 就能发现获取成功

最佳答案

查看完整内容

因为描述符只有作用在 类 层面上,Python 才会自动调用描述符的 __get__ 和 __set__ 而此时你的 test 是 Test 类的实例对象,那么 test.y = MyDes(4, 'y') 实际上是在创建一个 实例属性,即类中带 self.变量名 的属性,而不是类层面上的属性 可以实现,你只需将赋值过程用实例对象改成用类本身即可,如下代码: 即可成功创建了描述符,此时你在对实例进行 test.y 就能发现获取成功
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-15 17:10:31 | 显示全部楼层    本楼为最佳答案   

1、为什么会失败?原因在哪?


因为描述符只有作用在 类 层面上,Python 才会自动调用描述符的 __get__ 和 __set__

而此时你的 test 是 Test 类的实例对象,那么 test.y = MyDes(4, 'y') 实际上是在创建一个 实例属性,即类中带 self.变量名 的属性,而不是类层面上的属性

2、我这想法能实现吗?


可以实现,你只需将赋值过程用实例对象改成用类本身即可,如下代码:
Test.y = MyDes(4,'y')

即可成功创建了描述符,此时你在对实例进行 test.y 就能发现获取成功
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-15 19:38:12 | 显示全部楼层
1 描述符只能给类捆绑 实例化对象不能捆绑
2 能实现 可以不用描述符 使用代理类最简单
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-8-15 23:11:09 | 显示全部楼层
本帖最后由 阿奇_o 于 2021-8-15 23:16 编辑

这么说吧,"描述符",本身是为了"描述另一个类的特殊类"。

1. 特殊?特殊在哪?—— 特殊在它 有 __get__, __set__, __delete__, 这几个特殊方法,有这其一 就是"描述符"(__set_name__ 也可选)
    其次,还特殊在 要写正确这几个方法,必须遵守"描述器协议"(就是它的特定参数列表各需要写什么)

2. 描述另一个类?描述什么?—— 另一个类(或说是描述器的"owner")的【类变量】——该类的类变量指向描述器类对象
    这就好比,身残志坚某某作家,自己不能亲自写文章(类变量),但他请了打字员小王帮它写,
    这里小王就是"描述器",他和这个作家之间的协议约定就是"描述器协议"。
    —— 这里的关键是 必须是 类变量, 必须是 在类定义里 把类变量指向一个描述器类对象,如 x = MyDesp('小王')   
    —— 注意:若你写 实例变量 self.y = MyDesp('小王') 是没用的,描述器只针对 类变量

希望对你有帮助。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-13 19:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表