Using a base class function that takes parameters as a decorator for derived class function
我觉得在处理常规函数时,我对使用decorator有相当好的理解,但是在派生类中为decorator使用基类的方法和向decorator传递参数之间,我不知道下一步该怎么做。这是一段代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class ValidatedObject: ... def apply_validation(self, field_name, code): def wrap(self, f): self._validations.append(Validation(field_name, code, f)) return f return wrap class test(ValidatedObject): .... @apply_validation("_name","oh no!") def name_validation(self, name): return name =="jacob" |
如果我按原样尝试,我会得到一个"应用程序验证"没有找到。如果我和
有人能解释一下我做错了什么,以及解决这个问题的最佳方法吗?谢谢您。
您遇到的问题是,
最明显的一个方法是使用一个元类,它通过实例字典(实际上是类字典)进行搜索,并根据找到的内容设置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class ValidatedMeta(type): def __new__(meta, name, bases, dct): validations = [Validation(f._validation_field_name, f._validation_code, f) for f in dct.values if hasattr(f._validation_field_name)] dct["_validations"] = validations super(ValidatedMeta, meta).__new__(meta, name, bases, dct) def apply_validation(field_name, code): def decorator(f): f._validation_field_name = field_name f._validation_code = code return f return decorator def ValidatedObject(metaclass=ValidatedMeta): pass class test(ValidatedObject): @apply_validation("_name","oh no!") def name_validation(self, name): return name =="jacob" |
运行此代码后,
如果在继承层次结构的多个级别上定义了验证方法,则此代码可能不会执行所需的操作。上面写的元类只检查立即类的dict中是否有具有适当属性的方法。如果您需要它也包括
在类方法上使用decorators的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | from functools import wraps def VALIDATE(dec): @wraps(dec) def _apply_validation(self, name): self.validate(name) return dec(self, name) return _apply_validation class A: def validate(self, name): if name !="aamir": raise Exception, 'Invalid name"%s"' % name class B(A): @VALIDATE def name_validation(self, name): return name b = B() b.name_validation('jacob') # should raise exception |