Python 抽象方法上的装饰器
在python中,有没有一种方法可以使抽象方法上的装饰器贯彻到派生实现中 例如,在Python 抽象方法上的装饰器,python,decorator,abc,Python,Decorator,Abc,在python中,有没有一种方法可以使抽象方法上的装饰器贯彻到派生实现中 例如,在 import abc class Foo(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod @some_decorator def my_method(self, x): pass class SubFoo(Foo): def my_method(self, x): pri
import abc
class Foo(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
@some_decorator
def my_method(self, x):
pass
class SubFoo(Foo):
def my_method(self, x):
print x
据我所知,
subfo
的我的\u方法
不会被某个装饰者装饰。是否有某种方法可以实现这一点,而不必单独修饰Foo
的每个派生类?我的解决方案是扩展超类的方法而不重写它
import abc
class Foo(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
@some_decorator
def my_method(self, x):
pass
class SubFoo(Foo):
def my_method(self, x):
super().my_method(x) #delegating the call to the superclass
print x
据我所知,这在Python中是不可能的,也不是一个好的策略。这里有更多的解释
根据报告:
当abstractmethod()与其他方法描述符结合应用时,它应该作为最内部的装饰器应用,如以下使用示例所示:
换句话说,我们可以这样编写您的类(Python 3风格):
那又怎么样?如果您从AbstractClass
派生,并尝试重写info
属性,而不指定@property
装饰器,则会造成很大的混乱。请记住,为了简洁起见,属性(这只是一个示例)的类方法通常使用相同的名称:
class Concrete(AbstractMethod):
@property
def info(self):
return
@info.setter
def info(self, new_info):
new_info
在这种情况下,如果您没有重复@属性
和@info.setter
装饰器,就会造成混乱。用Python术语来说,这也行不通,属性放在类本身上,而不是实例上。换句话说,我想这是可以做到的,但在我看来,它最终会产生令人困惑的代码,这些代码不像重复几行装饰代码那么容易阅读。这当然是可能的。在Python中几乎没有什么做不到的,哈哈!我会让你决定这是否是个好主意
class MyClass:
def myfunc():
raise NotImplemented()
def __getattribute__(self, name):
if name == "myfunc":
func = getattr(type(self), "myfunc")
return mydecorator(func)
return object.__getattribute__(self, name)
(还没有测试语法,但应该给你一个想法)我将把它编码为两种不同的方法,就像在标准方法工厂模式描述中一样
Jinksy的回答对我不起作用,但稍加修改就起了作用(我用了不同的名字,但想法应该很清楚):
def my_decorator(func):
def包裹(自身、x、y):
打印('开始')
结果=func(self,x,y)
打印('结束')
返回结果
退货包装
A类(ABC):
@抽象方法
def f(自身、x、y):
通过
@我的装饰师
def f_装饰(自、x、y):
返回self.f(x,y)
B(A)类:
def f(自身、x、y):
返回x+y
B().f_(1,3)
[输出:]
开始
结束
4.
请注意,这与Jinksy编写的内容之间的重要区别在于,抽象方法是f,当调用B()时,调用的是继承的非抽象方法
据我所知,f_decoration
可以正确定义,因为abstractmethod
decorator没有干扰decoratormy_decorator
,我担心它只是具有广泛的魔力。调用抽象方法\u my\u method
并使用非抽象、非重写的my\u方法
是否是一种替代方法,它基本上可以一些装饰程序(self.\u my\u method)(*args,**kwds)
?@delnan-Hmm,是的,我希望在广泛的元类魔法和你的好建议之间可能会有一个解决方案,那就是稍微干净一点。但是我想我会做我必须做的。你试过这个吗?这违背了抽象方法的目的。抽象方法的全部思想是它们必须被子类重写。因此,您不会对其调用super()
。事实上,除了标记为抽象以确保未使用super()
之外,我通常会让我的抽象方法引发一个NotImplementedError
。使用抽象方法的默认实现没有什么错。
class MyClass:
def myfunc():
raise NotImplemented()
def __getattribute__(self, name):
if name == "myfunc":
func = getattr(type(self), "myfunc")
return mydecorator(func)
return object.__getattribute__(self, name)
class Foo(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
@some_decorator
def my_method(self, x):
self.child_method()
class SubFoo(Foo):
def child_method(self, x):
print x