在类上运行的属性装饰器(与实例相对),setter

时间:2017-11-21 16:27:05

标签: python python-3.x class properties python-decorators

在文档中详细讨论了属性修饰器,并讨论了解决它们的机制,但仅适用于getter 。我完全没有成功为未实例化的类创建。简单的例子:

我的物业装饰员

class ClassyProp(object):

    """ Classmethod + property """

    def __init__(self, input_func):
        log(f"ClassProp.__init__({input_func})")
        self.func = input_func

    def __get__(self, obj, cls=None):
        log(f"ClassProp.__get__({obj}, {cls})")
        return self.func

    def __set__(self, obj, value):
        log("__ClassyProp__.__set__()")

    def setter(self, fset):
        log("__ClassyProp__.setter()")

    def fset(*args):
        log("__ClassyProp__.fset()")

测试类

class foo(object):
    """ Test class """

    def __init__(self):
        pass

    @ClassyProp
    def f(cls):
        """ Test property_lazy_static get , set """
        pass

生成

print("======== ObjFoo ========")

ObjFoo = foo()
print(ObjFoo.f)
ObjFoo.f = 18
print(ObjFoo.f)

print("======== class foo ========")

print(foo.f)
foo.f = 15
print(foo.f)

产量

[      00s] ClassProp.__init__(<function foo.f at 0x7f4330c88268>)
======== ObjFoo ========
[      00s] ClassProp.__get__(<__main__.foo object at 0x7f4351522748>, <class '__main__.foo'>)
<function foo.f at 0x7f4330c88268>
[      00s] __ClassyProp__.__set__()
[      00s] ClassProp.__get__(<__main__.foo object at 0x7f4351522748>, <class '__main__.foo'>)
<function foo.f at 0x7f4330c88268>
======== class foo ========
[      00s] ClassProp.__get__(None, <class '__main__.foo'>)
<function foo.f at 0x7f4330c88268>
15

注意:如果我有ClassyProp个返回值,它就不会说出函数ID,请说出正确的get值,但我只想打印输出调试。

如您所见,为ObjFoo的实例正确调用了getter AND setter。但不适用于未实例化的类foo。在课堂上有一个属性设置器根本不可能吗?文档说明(我添加了休息符):

  

对于物体,机器在中     - object。 getattribute ()将b.x转换为
    - 键入(b)。 dict [&#39; x&#39;]。获取(b,键入(b))

     

实施通过优先链来实现     - 使数据描述符优先于实例变量,
    - 实例变量优先于非数据描述符,以及
    - 如果提供,则为 getattr ()分配最低优先级。

  

对于课程,机器在:
      - 键入。 getattribute ()将B.x转换为
      - B. dict [&#39; x&#39;]。获取(无,B)

两者都没有提及__set__。 ( get 显然适用于类和实例)

所以我现在想知道,这可能吗?我在文档中没有看到任何暗示它不是,但所有测试都表明了这一点。

0 个答案:

没有答案