Using property() on classmethods

后端 未结 15 910
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条回答
  •  半阙折子戏
    2020-11-22 17:43

    A property is created on a class but affects an instance. So if you want a classmethod property, create the property on the metaclass.

    >>> class foo(object):
    ...     _var = 5
    ...     class __metaclass__(type):  # Python 2 syntax for metaclasses
    ...         pass
    ...     @classmethod
    ...     def getvar(cls):
    ...         return cls._var
    ...     @classmethod
    ...     def setvar(cls, value):
    ...         cls._var = value
    ...     
    >>> foo.__metaclass__.var = property(foo.getvar.im_func, foo.setvar.im_func)
    >>> foo.var
    5
    >>> foo.var = 3
    >>> foo.var
    3
    

    But since you're using a metaclass anyway, it will read better if you just move the classmethods in there.

    >>> class foo(object):
    ...     _var = 5
    ...     class __metaclass__(type):  # Python 2 syntax for metaclasses
    ...         @property
    ...         def var(cls):
    ...             return cls._var
    ...         @var.setter
    ...         def var(cls, value):
    ...             cls._var = value
    ... 
    >>> foo.var
    5
    >>> foo.var = 3
    >>> foo.var
    3
    

    or, using Python 3's metaclass=... syntax, and the metaclass defined outside of the foo class body, and the metaclass responsible for setting the initial value of _var:

    >>> class foo_meta(type):
    ...     def __init__(cls, *args, **kwargs):
    ...         cls._var = 5
    ...     @property
    ...     def var(cls):
    ...         return cls._var
    ...     @var.setter
    ...     def var(cls, value):
    ...         cls._var = value
    ...
    >>> class foo(metaclass=foo_meta):
    ...     pass
    ...
    >>> foo.var
    5
    >>> foo.var = 3
    >>> foo.var
    3
    

提交回复
热议问题