此示例中还有其他一些问题,但是有个疑问,您要做的就是包装属性时
包装属性时,请包装其__get__方法:
class MyObject(object): def method(self): print "method called on %s" % str(self) @property def result(self): return "Some derived property" def common(self, a=None): print selfdef my_decorator(func): def _wrapped(*args, **kwargs): print "Calling decorated function %s" % func return func(*args, **kwargs) return _wrappedclass WrappedObject(object): def __init__(self, cls): for attr, item in cls.__dict__.items(): if attr != '__init__' and callable(item): setattr(cls, attr, my_decorator(item)) elif isinstance(item, property): new_property = property(my_decorator(item.__get__), item.__set__, item.__delattr__) setattr(cls, attr, new_property) self._cls = cls def __call__(self, *args, **kwargs): return self._cls(*args, **kwargs)inst = WrappedObject(MyObject)()
那就是对完成任务的代码的简单修改。但是,为了避免重新编写其属性,我将其更改为包装的类的子类。您可以通过编程简单地创建带有名称的类型,带有基数的元组和以dict为参数的子类,从而以编程方式创建子类。
编辑-将代码更改为子类包装的类实际上,对给定类进行子类化几乎不需要对给定代码进行任何修改,但是对于
type我指出的调用而言。我刚刚在这里进行了测试-
将WrappedObject类更改为:
class WrappedObject(object): def __init__(self, cls): dct = cls.__dict__.copy() for attr, item in dct.items(): if attr != '__init__' and callable(item): dct[attr] = my_decorator(item) elif isinstance(item, property): new_property = property(my_decorator(item.__get__), item.__set__, item.__delattr__) dct[attr] = new_property self._cls = type("wrapped_" + cls.__name__, (cls,), dct) def __call__(self, *args, **kwargs): return self._cls(*args, **kwargs)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)