免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 22380 | 回复: 2
打印 上一主题 下一主题

python描述符问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2020-05-18 17:54 |只看该作者 |倒序浏览
# 此程序用于使用魔方方法访问、更改、删除实例属性
class MyProperty:
    def __init__(self, fget=None, fset=None, fdel=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel

    def __get__(self, instance, owner):
        name=self.fget
        print('name=', name)
        return name(instance)

    def __set__(self, instance, value):
        self.fset(instance, value)

    def __delete__(self, instance):
        self.fdel(instance)


class C:
    def __init__(self):
        self._x = None

    def getX(self):
        return self._x

    def setX(self, value):
        self._x = value

    def delX(self):
        del self._x

    # 此为描述符将类的实例赋值给另一个类的变量
    x = MyProperty(getX, setX, delX)
疑问1:在__get__(self, instance, owner)方法中,返回的是self.fget(instance),也就是用‘方法名(实例名)’的方式访问C的实例方法,但访问实例方法应该用‘实例名.方法名()'的方式访问才对,把self.fget(instance)改为instance.(self.fget())运行会报错,为什么?
疑问2::把__get__(self, instance, owner)方法中的self.fget(instance)改为instance.getX()就能正常运行,而用instance.self.fget()就会出错,但self.fget = getX,二者应该是等价的啊,应该都能运行才对。

论坛徽章:
8
2016科比退役纪念章
日期:2018-10-24 08:24:0115-16赛季CBA联赛之北控
日期:2019-03-12 14:34:562016科比退役纪念章
日期:2019-04-01 10:33:0915-16赛季CBA联赛之山东
日期:2019-04-17 12:46:3215-16赛季CBA联赛之广夏
日期:2019-05-09 16:40:4015-16赛季CBA联赛之广夏
日期:2019-10-10 15:33:4015-16赛季CBA联赛之辽宁
日期:2019-10-15 08:37:0615-16赛季CBA联赛之北控
日期:2021-03-30 15:53:34
2 [报告]
发表于 2020-05-25 16:31 |只看该作者
楼主的代码应该是用 描述符类来模拟内建的 property 装饰器。
我感觉描述符类 对python初学者 是一个小小的难点,我自己可能也理解的不够深入,还是要多翻书,多实践。

你这两个问题 应该就是一个问题。
你说  "实例方法应该用‘实例名.方法名()'的方式访问才对",  是的  所以你第二个问题中的
  1. instance.getX()
复制代码
就正常。

  1. instance.(self.fget())
复制代码
这个肯定报的是语法错误了。
instance 就是C的实例,又是点,又是括号,你到底是要调用属性还是方法呢?没有这种语法。所以报语法错误。
问题2中
  1. instance.self.fget()
复制代码

就是上面的写法没有括号,这样写法的意思 是先调用instance就是C实例的self属性,显然C没有名字叫"self"的属性,所以会报AttributeError。
  1. self.fget = getX
复制代码
大概可以理解为 描述类实例的属性指向了一个函数的引用。这不等于任何情况下就能 直接的替换!  这里你把描述符的 self.fget()跟在了另一个类C的实例instance的后面 显然是错误的。

论坛徽章:
8
2016科比退役纪念章
日期:2018-10-24 08:24:0115-16赛季CBA联赛之北控
日期:2019-03-12 14:34:562016科比退役纪念章
日期:2019-04-01 10:33:0915-16赛季CBA联赛之山东
日期:2019-04-17 12:46:3215-16赛季CBA联赛之广夏
日期:2019-05-09 16:40:4015-16赛季CBA联赛之广夏
日期:2019-10-10 15:33:4015-16赛季CBA联赛之辽宁
日期:2019-10-15 08:37:0615-16赛季CBA联赛之北控
日期:2021-03-30 15:53:34
3 [报告]
发表于 2020-05-25 16:33 |只看该作者
本帖最后由 cfwyy 于 2020-05-26 07:57 编辑

论坛的回复有时候有问题,多回了一次。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP