假设我们有多个函数都接受一个URL作为它们的第一个参数,这个URL需要验证。这可以很好地解决与装饰
def validate_url(f):
def validated(url, *args, **kwargs):
assert len(url.split('.')) == 3 # trivial example
return f(url, *args, **kwargs)
return validated
@validate_url
def some_func(url, some_other_arg, *some_args, **some_kwargs):
pass
这种方法将起作用,并允许我将验证行为从许多类似函数的实例中剔除。但是现在我想写一个类方法,它也需要一个经过验证的URL。然而,这种天真的方法是行不通的
class SomeClass:
@validate_url
def some_method(self, url, some_other_args):
pass
因为我们最终将尝试验证self
,而不是url
。我的问题是如何用最少的样板编写一个既适用于函数又适用于方法的装饰器。你知道吗
注1:我知道为什么会发生这种情况,只是我不知道如何以最优雅的方式解决这个问题。你知道吗
注2:URL验证问题只是一个例子,因此检查isinstance(args[0], str)
是否不是一个好的解决方案。你知道吗
一种解决方案是以某种方式检测修饰函数是否是类方法——这似乎很难做到(如果不是不可能的话)(据我所知)。
inspect
模块的ismethod()
和isfunction()
在类定义中使用的装饰器中不起作用。你知道吗考虑到这一点,这里有一种有点老套的方法来检查修饰的callable的第一个参数是否被命名为
"self"
,这是它在类方法中的编码约定(尽管它不是一个要求,所以caveat emptor,使用风险自负)。你知道吗下面的代码似乎可以在python2和python3中使用。然而,在python3中,它可能会引发
DeprecationWarning
,具体取决于所使用的子版本,因此它们在下面的代码部分中被抑制了。你知道吗输出:
相关问题 更多 >
编程相关推荐