这是我的处理方式:
class ClassPropertyDescriptor(object): def __init__(self, fget, fset=None): self.fget = fget self.fset = fset def __get__(self, obj, klass=None): if klass is None: klass = type(obj) return self.fget.__get__(obj, klass)() def __set__(self, obj, value): if not self.fset: raise AttributeError("can't set attribute") type_ = type(obj) return self.fset.__get__(obj, type_)(value) def setter(self, func): if not isinstance(func, (classmethod, staticmethod)): func = classmethod(func) self.fset = func return selfdef classproperty(func): if not isinstance(func, (classmethod, staticmethod)): func = classmethod(func) return ClassPropertyDescriptor(func)class Bar(object): _bar = 1 @classproperty def bar(cls): return cls._bar @bar.setter def bar(cls, value): cls._bar = value# test instance instantiationfoo = Bar()assert foo.bar == 1baz = Bar()assert baz.bar == 1# test static variablebaz.bar = 5assert foo.bar == 5# test setting variable on the classBar.bar = 50assert baz.bar == 50assert foo.bar == 50在我们打电话时
Bar.bar,设置员没有工作 ,因为我们正在打电话
TypeOfBar.bar.__set__,而不是
Bar.bar.__set__。
添加元类定义可以解决此问题:
class ClassPropertymetaClass(type): def __setattr__(self, key, value): if key in self.__dict__: obj = self.__dict__.get(key) if obj and type(obj) is ClassPropertyDescriptor: return obj.__set__(self, value) return super(ClassPropertymetaClass, self).__setattr__(key, value)# and update class define:# class Bar(object):# __metaclass__ = ClassPropertymetaClass# _bar = 1# and update ClassPropertyDescriptor.__set__# def __set__(self, obj, value):# if not self.fset:#raise AttributeError("can't set attribute")# if inspect.isclass(obj):#type_ = obj#obj = None# else:#type_ = type(obj)# return self.fset.__get__(obj, type_)(value)现在一切都会好起来的。



