[英]Using a base class function that takes parameters as a decorator for derived class function
我觉得我在处理常规函数时非常了解使用装饰器,但是在派生类中使用装饰器的基类方法和将参数传递给所述装饰器之间,我不知道下一步该怎么做。 这是一段代码。
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"
如果按原样尝试,则会发现找不到“ apply_validation”。
如果我使用@self.apply_validation
尝试,则@self.apply_validation
“自我”。
我也一直在使apply_validation
成为一个没有成功的类方法。
有人可以解释我在做什么错,以及解决此问题的最佳方法吗? 谢谢。
只是在类方法上使用装饰器的示例:
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
您遇到的问题是apply_validation
是一个方法,这意味着您需要在ValidatedObject
的实例上调用它。 不幸的是,在调用它的时候(在test
类的定义期间),没有合适的实例可用。 您需要一种不同的方法。
最明显的一个方法是使用一个元类来搜索其实例字典(实际上是类字典),并根据找到的内容设置_validations
变量。 您仍然可以使用装饰器,但是它可能应该是全局函数或静态方法,并且需要以不同的方式工作。 这是一些代码,使用元类和添加函数属性的装饰器:
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"
此代码运行后, test._validations
将为[Validation("_name", "oh no!", test.name_validation)]
。 请注意,传递给Validation
是未绑定的,因此您在调用它时需要自己传递一个self
参数(或者删除self
参数并更改apply_validation
创建的装饰器以返回staticmethod(f)
)。 。
如果您在继承层次结构的多个级别上定义了验证方法,则此代码可能无法执行您想要的操作。 上面编写的元类仅检查直接类的dict是否具有适当属性的方法。 如果您还需要在_validations
包括继承的方法, _validations
可能需要修改ValidatedMeta.__new__
的逻辑。 可能是要走的最简单的方法是看_validations
在属性bases
并连接列表在一起。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.