Python 强制执行抽象方法实现是非语法的吗?
在设计类时,抽象方法非常有用。据我所知,Python没有强制执行继承类以实现抽象方法的机制。在我的代码中(参见下面的示例),我在基类中输入了一个失败的断言,如果没有实现,就会导致运行时错误。这是非音速的吗Python 强制执行抽象方法实现是非语法的吗?,python,oop,Python,Oop,在设计类时,抽象方法非常有用。据我所知,Python没有强制执行继承类以实现抽象方法的机制。在我的代码中(参见下面的示例),我在基类中输入了一个失败的断言,如果没有实现,就会导致运行时错误。这是非音速的吗 class Dog(Animal): def speak(self): return "bark" class Animal(): def speak(self): assert(False) #abstract 好吧,如果您没有在基类中包含方法speak,并且碰巧使用
class Dog(Animal):
def speak(self):
return "bark"
class Animal():
def speak(self):
assert(False) #abstract
好吧,如果您没有在基类中包含方法
speak
,并且碰巧使用了它,那么代码无论如何都会失败。问题是,它的可能性有多大,以及如何告诉用户(一个NotImplementedError
可能比一个断言更适合这里)。Python实际上有抽象类和抽象方法:
>>> 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
>>>
如果出于某种原因,您不能使用@abstractmethod
,但仍希望获得该效果,则应提出NotImplementedError
。您可能希望这样做,因为您确实需要该类的实例,其中一些可能不需要实现可选功能。您仍然应该考虑通过super()
调用函数的可能性。第一个近似值可能是这样的
class Foo(object):
def bar(self, baz):
if self.bar.im_func == Foo.bar.im_func:
raise NotImplementedError, "Subclasses must implement bar"
一般来说,python并不总是能够直接对代码实施限制,至少从面向对象的角度来看是如此(考虑抽象类、私有方法等等)。 要强制子类实现方法,您可能需要执行以下操作:
class Animal():
def speak(self):
raise NotImplementedError #abstract
class Dog(Animal):
def speak(self):
return "bark"
class MuteAnimal(Animal):
pass
这并不意味着该方法将由子类实现,但它将在不执行Salk方法时简单地引发错误。
< P> ABC是C++的伪品,与鸭类型相反。如果类动物不定义说话
,它会毫不费力地做你想做的事
>>> class Animal(object):
... pass
...
>>> class Dog(Animal):
... def speak(self):
... print "bark"
...
>>> animal = Animal()
>>> dog = Dog()
>>> animal.speak()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Animal' object has no attribute 'speak'
>>> dog.speak()
bark
类动物(对象):
... 通过
...
>>>犬类(动物):
... def发言(自我):
... 打印“树皮”
...
>>>动物
>>>狗
>>>动物说话
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:“Animal”对象没有属性“speak”
>>>狗说话
树皮
C++和相关语言强制您创建ABC,因为ABC实际上是一个接口描述。Python避免编译器强制执行的接口声明,因为它们试图在代码中记录通过非语言手段更好地执行的契约。“Python避免编译器强制执行的接口声明,因为它们试图在代码中记录通过非语言手段更好地执行的契约。”WTF?请澄清这句话,它可能会对其他人更有帮助。此外,如果你要求你的库的用户在类中实现一个混合的方法,ABC和/或抽象方法在duck类型世界中是完全有效的。如果它是正确的软件工程,谁会在乎它是“非语法化”还是与特定社区灌输的信仰背道而驰呢。看看下面这个家伙的答案,忽略这个家伙。
>>> class Animal(object):
... pass
...
>>> class Dog(Animal):
... def speak(self):
... print "bark"
...
>>> animal = Animal()
>>> dog = Dog()
>>> animal.speak()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Animal' object has no attribute 'speak'
>>> dog.speak()
bark