Using property() on classmethods

后端 未结 15 874
Happy的楠姐
Happy的楠姐 2020-11-22 16:55

I have a class with two class methods (using the classmethod() function) for getting and setting what is essentially a static variable. I tried to use the property() functi

15条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-22 17:53

    There is no reasonable way to make this "class property" system to work in Python.

    Here is one unreasonable way to make it work. You can certainly make it more seamless with increasing amounts of metaclass magic.

    class ClassProperty(object):
        def __init__(self, getter, setter):
            self.getter = getter
            self.setter = setter
        def __get__(self, cls, owner):
            return getattr(cls, self.getter)()
        def __set__(self, cls, value):
            getattr(cls, self.setter)(value)
    
    class MetaFoo(type):
        var = ClassProperty('getvar', 'setvar')
    
    class Foo(object):
        __metaclass__ = MetaFoo
        _var = 5
        @classmethod
        def getvar(cls):
            print "Getting var =", cls._var
            return cls._var
        @classmethod
        def setvar(cls, value):
            print "Setting var =", value
            cls._var = value
    
    x = Foo.var
    print "Foo.var = ", x
    Foo.var = 42
    x = Foo.var
    print "Foo.var = ", x
    

    The knot of the issue is that properties are what Python calls "descriptors". There is no short and easy way to explain how this sort of metaprogramming works, so I must point you to the descriptor howto.

    You only ever need to understand this sort of things if you are implementing a fairly advanced framework. Like a transparent object persistence or RPC system, or a kind of domain-specific language.

    However, in a comment to a previous answer, you say that you

    need to modify an attribute that in such a way that is seen by all instances of a class, and in the scope from which these class methods are called does not have references to all instances of the class.

    It seems to me, what you really want is an Observer design pattern.

提交回复
热议问题