cls behaviour in inherited classmethod of a decorated class
我正在尝试使用调用类方法时使用的参数之一对类的类方法进行验证。
为此,我将为类使用一个decorator,该类将对所需方法应用decorator,该方法将使用函数中的一个参数执行验证函数。
这对于基类(在本例中,我将称之为
但是,如果我创建另一个继承
举个例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | import inspect def is_number(word): if word.isdigit(): print('Validation passed') else: raise Exception('Validation failed') class ClassDecorator(object): def __init__(self, *args): self.validators = args def __decorateMethod(self): def wrapped(method): def wrapper(cls, word, *args, **kwargs): for validator in self.validators: validator(word) return method(word, *args, **kwargs) return wrapper return wrapped def __call__(self, cls): for name, method in inspect.getmembers(cls): if name == 'shout': decoratedMethod = self.__decorateMethod()(method) setattr(cls, name, classmethod(decoratedMethod)) return cls @ClassDecorator(is_number) class Parent(object): @classmethod def shout(cls, word): print('{} is shouting {}'.format(cls, word)) @classmethod def say(cls): print('{} is talking'.format(cls)) class Child(Parent): pass Parent.shout('123') Child.shout('321') |
将产生以下输出:
1 2 3 4 | Validation passed <class '__main__.Parent'> is shouting 123 Validation passed <class '__main__.Parent'> is shouting 321 |
号
我的问题是:
- 为什么用
Parent 作为cls调用Child 的classmethod - 是否有可能使用这种设计来获得想要的行为?
P.S.:我在python 2.7.10和python 3.5.2上都试过,并且得到了相同的行为
您正在修饰绑定类方法;正是这个对象持有
先解包classmethods,就可以得到具有
1 2 3 4 5 6 | def __call__(self, cls): for name, method in inspect.getmembers(cls): if name == 'shout': decoratedMethod = self.__decorateMethod()(method.__func__) setattr(cls, name, classmethod(decoratedMethod)) return cls |
现在必须考虑包装器也在处理未绑定的函数,因此传递
1 2 3 4 5 | # pass in cls explicitly: return method(cls, word, *args, **kwargs) # or bind the descriptor manually: return method.__get__(cls)(word, *args, **kwargs) |
号