强制抽象方法实现是非Python的吗? [英] Is enforcing an abstract method implementation unpythonic?

查看:75
本文介绍了强制抽象方法实现是非Python的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在设计类时,抽象方法可能会非常有帮助.据我所知,Python没有用于强制继承类以实现抽象方法的机制.在我的代码中(请参见下面的示例),我在基类中输入了失败的断言,如果未实现,则会导致运行时错误.这是非蟒蛇的吗?

When designing classes abstract methods can be very helpful. From what I know, Python does not have a mechanism for enforcing an inherited class to implement the abstract method. In my code (see example below) I enter a failed assertion in the base class to cause a runtime error if not implemented. Is this unpythonic?

class Dog(Animal):
  def speak(self):
   return "bark"

class Animal():
  def speak(self):
   assert(False) #abstract

推荐答案

Python实际上确实具有带有abstact方法的抽象类:

Python actually does have abstract classes with abstact methods:

>>> import abc
>>> 
>>> class IFoo(object):
...     __metaclass__ = abc.ABCMeta
...     
...     @abc.abstractmethod
...     def foo(self):
...         pass
... 
>>> foo = IFoo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Cant instantiate abstract class IFoo with abstract methods foo
>>> class FooDerived(IFoo):
...     pass
... 
>>> foo = FooDerived()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Cant instantiate abstract class FooDerived with abstract methods foo
>>> class FooImplements(FooDerived):
...     def foo(self):
...         print "foo'ed"
... 
>>> foo = FooImplements()
>>> foo.foo()
foo'ed
>>> 

另一方面,是这个pythonic" 的基本问题很难说.如果您的目的是提供抽象基类,以便以后可以检查以确保值继承自该基类,则不,这不是特别的pythonic,即使有可能使您的基类的任意类型的抽象子类成为可能.另一方面,最好提供一个抽象基类,该基类基于具体子类中提供的实现来实现某些功能.例如,collections.Sequencecollections.Mapping只是对list like和dict like类执行此操作;子类可以提供__getitem__,可以免费获取__contains__和其他.

On the other hand, the fundamental question of "is this pythonic" is a bit harder to say. If your intent is to provide the abstract base class so that you can later check to make sure that values inherit from it, then no, that's not particularly pythonic, even though it's possible to make arbitrary types abstract subclasses of your baseclass. On the other hand, it's perfectly fine to provide an abstract baseclass that implements some functionality based upon the implementation provided in concrete subclasses. For example, collections.Sequence and collections.Mapping do just this for list like and dict like classes; subclasses can provide __getitem__ and can get __contains__ and others for free.

可以肯定的是,除了记录代码的期望之外,您永远不要使用assert().如果断言实际上有可能失败,则不应使用断言.优化的python(python -O script.py)不检查断言.

For certain, you should never use assert() except to document the expectations of code; If it's actually possible for the assert to fail, you shouldn't be using an assert. Optimized python (python -O script.py) does not check assertions.

更多说明:

如果要检查值的类型:

def foo(bar):
    if not isinstance(bar, AbstractBaz):
        raise ValueError, ("bar must be an instance of AbstractBaz, "
                           "got %s" % type(bar))

如果由于某种原因您不能使用@abstractmethod,但仍希望获得这种效果,则应提高NotImplementedError.您可能想要这样做,因为您实际上确实想要该类的实例,其中某些实例可能不需要实现可选功能.您仍然应该考虑通过super()调用该函数的可能性.初步估算,可能看起来像这样.

If for some reason you can't use @abstractmethod, but still want that effect, you should raise NotImplementedError. You might want to do this because you actually do want instances of that class, some of which might not need to implement optional functionality. You still should account for the possibility that the function was called through super(). To a first approximation, that might look like this.

class Foo(object):
    def bar(self, baz):
        if self.bar.im_func == Foo.bar.im_func:
            raise NotImplementedError, "Subclasses must implement bar"

这篇关于强制抽象方法实现是非Python的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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