为什么在定义为实例属性时未调用描述符?

发布于 2021-01-29 18:03:02

当我将“数据”变量设为类变量时,以下工作有效,但是当我将其变为对象变量时,则不会调用描述符。请帮忙。

class Data(object):
    products = {
        'milk': {'price': 1.50, 'quantity': 10},
        'eggs': {'price': 0.20, 'quantity': 100},
        'cheese': {'price': 2.00, 'quantity': 10}
    }
    def __get__(self, obj, klas):
        print "Here in descriptor"
        return self.products

class BusinessLogic(object):
    def __init__(self):         # When I remove these 2 lines 
        self.data = Data()
    #data = Data()             # and enable this line it does work !

def main():
    b = BusinessLogic()
    b.data

if __name__ == '__main__':
    main()
关注者
0
被浏览
49
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    这是因为描述符仅应定义为类属性,而不是实例属性:

    文档

    以下方法仅在包含该方法的类的实例(所谓的描述符类)出现在所有者类中( 描述符必须位于所有者的类字典或父类的父类的类字典中 )时适用。

    为了使描述符也能与实例属性一起使用,您需要重写。__getattribute__方法BusinessLogic(尚未进行全面测试,但可以根据情况工作):

    def __getattribute__(self, attr):
            obj = object.__getattribute__(self, attr)
            if hasattr(obj, '__get__'):
                return obj.__get__(self, type(self))
            return obj
    

    如果您有数据描述符,则还需要处理该__setattr__零件。

    def __setattr__(self, attr, val):
        try:
            obj = object.__getattribute__(self, attr)
        except AttributeError:
            # This will be raised if we are setting the attribute for the first time
            # i.e inside `__init__` in your case.
            object.__setattr__(self, attr, val)
        else:
            if hasattr(obj, '__set__'):
                obj.__set__(self, val)
            else:
                object.__setattr__(self, attr, val)
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看