Python抽象基类可以强制执行函数签名吗? [英] Can a Python Abstract Base Class enforce function signatures?

查看:115
本文介绍了Python抽象基类可以强制执行函数签名吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我定义了一个抽象基类

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆