鱼C论坛

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

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

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

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

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

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

  16. test = Test()


复制代码



上面代码正常运行后,正常调用x,何修改x。

  1. >>> test.x
  2. 现在获取变量x
  3. 10
  4. >>> test.x = 1
  5. 变量x在修改
复制代码


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


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

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


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

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

2、我这想法能实现吗?


可以实现,你只需将赋值过程用实例对象改成用类本身即可,如下代码:

  1. Test.y = MyDes(4,'y')
复制代码


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

最佳答案

查看完整内容

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

使用道具 举报

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

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


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

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

2、我这想法能实现吗?


可以实现,你只需将赋值过程用实例对象改成用类本身即可,如下代码:

  1. Test.y = MyDes(4,'y')
复制代码


即可成功创建了描述符,此时你在对实例进行 test.y 就能发现获取成功
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-8-15 19:38:12 | 显示全部楼层
1 描述符只能给类捆绑 实例化对象不能捆绑
2 能实现 可以不用描述符 使用代理类最简单
小甲鱼最新课程 -> https://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('小王') 是没用的,描述器只针对 类变量

希望对你有帮助。

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-20 03:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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