Python抽象基类可以强制执行函数签名吗? [英] Can a Python Abstract Base Class enforce function signatures?
问题描述
假设我定义了一个抽象基类,
from abc import abstractmethod, ABCMeta
class Quacker(object):
__metaclass__ = ABCMeta
@abstractmethod
def quack(self):
return "Quack!"
这确保了任何从Quacker
派生的类都必须实现quack
方法.但是,如果我定义以下内容:
This ensures any class deriving from Quacker
must implement the quack
method. But if I define the following:
class PoliteDuck(Quacker):
def quack(self, name):
return "Quack quack %s!" % name
d = PoliteDuck() # no error
由于我提供了quack
方法,因此允许实例化该类,但函数签名不匹配.我可以看到这在某些情况下可能有用,但是我有兴趣确保我可以绝对调用抽象方法.如果功能签名不同,则可能会失败!
I'm allowed to instantiate the class because I've provided the quack
method, but the function signatures don't match. I can see how this might be useful in some situations, but I'm in interested in ensuring I can definitely call the abstract methods. This might fail if the function signature is different!
所以:我如何强制执行匹配的函数签名?如果签名不匹配,那么在创建对象时会出现错误,就像我根本没有定义它一样.
So: how can I enforce a matching function signature? I would expect an error when creating the object if the signatures don't match, just like if I hadn't defined it at all.
我知道,这不是惯用语言,如果我想要这些保证,那么Python是使用的错误语言,但是这很重要-是有可能吗?
I know that this is not idiomatic, and that Python is the wrong language to be using if I want these sorts of guarantees, but that's beside the point - is it possible?
推荐答案
这比您想像的还要糟糕.抽象方法仅按名称进行跟踪,因此您甚至不必使quack
成为实例化子类的方法.
It's worse than you think. Abstract methods are tracked by name only, so you don't even have to make quack
a method in order to instantiate the child class.
class SurrealDuck(Quacker):
quack = 3
d = SurrealDuck()
print d.quack # Shows 3
系统中没有任何东西可以强制quack
甚至是可调用对象,更不用说其参数与抽象方法的原始方法匹配的对象了.充其量,您可以子类化ABCMeta
并自己添加代码,以将子代中的类型签名与父代中的原始签名进行比较,但这并不容易实现.
There is nothing in the system that enforces that quack
is even a callable object, let alone one whose arguments match the abstract method's original. At best, you could subclass ABCMeta
and add code yourself to compare type signatures in the child to the originals in the parent, but this would be nontrivial to implement.
(当前,将某物标记为抽象"实质上只是将名称添加到父级中的冻结set属性中(Quacker.__abstractmethods__
).使一个类可实例化就像将此属性设置为一个空的iterable一样简单)进行测试.)
(Currently, marking something as "abstract" essentially just adds the name to a frozen set attribute in the parent (Quacker.__abstractmethods__
). Making a class instantiable is as simple as setting this attribute to an empty iterable, which is useful for testing.)
这篇关于Python抽象基类可以强制执行函数签名吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!