Python 摆脱显式超链接
我想实现这样的东西Python 摆脱显式超链接,python,python-3.x,python-decorators,Python,Python 3.x,Python Decorators,我想实现这样的东西 def after(f): def inner(*args, **kwargs): super().f(*args, **kwargs) f(*args, **kwargs) return inner class A: def f(self): print ('hello') class B(A): @after def f(self): print ('world') b = B() b
def after(f):
def inner(*args, **kwargs):
super().f(*args, **kwargs)
f(*args, **kwargs)
return inner
class A:
def f(self):
print ('hello')
class B(A):
@after
def f(self):
print ('world')
b = B()
b.f()
也就是说,我想在我的一些类中去掉显式的super
,并用@before
/@before
decorator(可能带有参数)替换它
也就是说,在本例中,我希望打印hello world
这样做的目的是提高代码的可读性,因为在某些类中我经常使用多重继承,所以我经常重写方法,并且经常必须使用
super()
我想我可以使用inspect
来确定调用decorator的类实例(尽管如果我有许多类实例,则不确定性能)
有没有一种方法可以在不牺牲性能的情况下实现这一点?您可以让decorator正常工作,您只需要将它变成一个描述符类,而不是一个函数。您需要实现
\uuuu set\u name\uuuu
方法来获取对已添加到的类的引用。使用类引用,您可以进行双参数super
调用:
import functools
class after:
def __init__(self, method):
self.method = method
def __set_name__(self, owner, name):
self.owner = owner
self.name = name # using self.method.__name__ might be better?
def __get__(self, instance, owner):
if instance is None:
return self
return functools.partial(self, instance)
def __call__(self, instance, *args, **kwargs):
assert(self.owner is not None and self.name is not None)
getattr(super(self.owner, instance), self.name)(*args, **kwargs)
return self.method(instance, *args, **kwargs)
您也可以在之前执行一个,这几乎是相同的,只是最后两行的顺序相反(并对返回值进行一些处理)
我要注意的是,这个decorator通常没有正常方式调用super
有用,因为您无法有效地与重写方法返回的值交互,也无法更改传递给它的参数。没有任何before
或before
修饰方法可以复制这些类:
class Foo:
def foo(self, x, y):
return x + y
class Bar(Foo):
def foo(self, x, y, z):
return super().foo(x//2, y+1) * z
调用super()
有什么不对?使用这样的装饰器如何改善这种情况?其目的是提高代码的可读性。我必须经常编写类似于super()的东西。一些方法(*args,**kwargs)
。也就是说,我不想重复自己指定python可以自动获取的方法和参数(在super()
行中)。使用super()
比创建只有您使用的新包装更具可读性。@me2只认为这会降低代码的可读性。1) 没有那么明确。2) 它混淆了执行顺序,因为该函数的实际内容现在已经以装饰器的形式移到了它之外。所以,如果你想知道发生了什么,你必须在body和decorator之间来回跳跃,看看这个函数应该做什么。decorator是用来扩充功能的,而不是吞下部分内容。3)它不会在代码行方面保存任何内容。酷!请更正输入错误。是的,这不是一种通用的方法,我还要补充一点,有时为不同的类调用super
可能会有用,或者有时您可能需要在之前和之后。但这两个装饰师似乎足以满足我的大部分需求。谢谢