如何在Python中实现虚拟方法?
我知道PHP或Java中的虚拟方法 如何在Python中实现它们如何在Python中实现虚拟方法?,python,virtual-functions,Python,Virtual Functions,我知道PHP或Java中的虚拟方法 如何在Python中实现它们 或者我必须在抽象类中定义一个空方法并重写它?Python方法总是虚拟的。当然,您甚至不必在基类中定义方法。在Python中,方法优于虚拟方法——它们是完全动态的,因为Python中的类型是duck类型 Python中的Cat和Dog甚至不必从公共基类派生来允许这种行为-您可以免费获得它。也就是说,一些程序员更喜欢以一种更严格的方式定义他们的类层次结构,以便更好地对其进行文档记录,并对类型施加一些严格的限制。这也是可能的-请参见示例
或者我必须在抽象类中定义一个空方法并重写它?Python方法总是虚拟的。当然,您甚至不必在基类中定义方法。在Python中,方法优于虚拟方法——它们是完全动态的,因为Python中的类型是duck类型
Python中的
Cat
和Dog
甚至不必从公共基类派生来允许这种行为-您可以免费获得它。也就是说,一些程序员更喜欢以一种更严格的方式定义他们的类层次结构,以便更好地对其进行文档记录,并对类型施加一些严格的限制。这也是可能的-请参见示例。实际上,在2.6版中,python提供了一种称为抽象基类的东西,您可以显式地设置如下虚拟方法:
from abc import ABCMeta
from abc import abstractmethod
...
class C:
__metaclass__ = ABCMeta
@abstractmethod
def my_abstract_method(self, ...):
如果类不从已经使用元类的类继承,那么它工作得非常好
资料来源:
Python方法总是虚拟的 就像伊格纳西奥说的那样 不知何故,类继承可能是实现所需功能的更好方法
class Animal:
def __init__(self,name,legs):
self.name = name
self.legs = legs
def getLegs(self):
return "{0} has {1} legs".format(self.name, self.legs)
def says(self):
return "I am an unknown animal"
class Dog(Animal): # <Dog inherits from Animal here (all methods as well)
def says(self): # <Called instead of Animal says method
return "I am a dog named {0}".format(self.name)
def somethingOnlyADogCanDo(self):
return "be loyal"
formless = Animal("Animal", 0)
rover = Dog("Rover", 4) #<calls initialization method from animal
print(formless.says()) # <calls animal say method
print(rover.says()) #<calls Dog says method
print(rover.getLegs()) #<calls getLegs method from animal class
raisenotimplementederror()
对于不实现方法的“抽象”基类的“纯虚拟方法”,这是推荐的例外
说:
此异常源于RuntimeError
。在用户定义的基类中,抽象方法在要求派生类重写该方法时应引发此异常
正如其他人所说,这主要是一种文档约定,不是必需的,但这样您可以得到一个比缺少属性错误更有意义的异常
例如:
给出:
2
Traceback (most recent call last):
File "./a.py", line 13, in <module>
Base().usesVirtualMethod()
File "./a.py", line 6, in usesVirtualMethod
return self.virtualMethod() + 1
File "./a.py", line 4, in virtualMethod
raise NotImplementedError()
NotImplementedError
2
回溯(最近一次呼叫最后一次):
文件“/a.py”,第13行,在
Base().usesVirtualMethod()
文件“/a.py”,第6行,使用虚拟方法
返回self.virtualMethod()+1
文件“/a.py”,第4行,采用虚拟方法
引发未实现的错误()
未实现错误
相关:
类似于C++中的一种虚拟方法(通过引用或指向基类的指针调用派生类的方法)在Python中没有意义,因为Python没有键入。(但我不知道虚拟方法在Java和PHP中是如何工作的。)
但是,如果说“虚拟”是指调用继承层次结构中最底层的实现,那么正如一些答案所指出的那样,在Python中总是会得到这样的结果 嗯,几乎总是 正如dplamp所指出的,并非Python中的所有方法都是这样的。邓德方法不适用。我认为这是一个不太为人所知的特征 考虑这个人为的例子class A:
def prop_a(self):
return 1
def prop_b(self):
return 10 * self.prop_a()
class B(A):
def prop_a(self):
return 2
现在
但是,请考虑这一项
class A:
def __prop_a(self):
return 1
def prop_b(self):
return 10 * self.__prop_a()
class B(A):
def __prop_a(self):
return 2
现在
我们所做的唯一更改是使prop_a()
成为dunder方法
第一个行为的问题可能是,在不影响
prop\u b()
的行为的情况下,无法更改派生类中prop\u A()
的行为。Raymond Hettinger的《非常好的谈话》给出了一个不方便使用的用例示例。+1为例。顺便问一下,狗用什么语言说“hau”?@JeremyP:嗯,说得好:-)我猜在语言中,“h”的发音类似于西班牙语中“hippy”或“Javier”的第一个字母。@Eli:对不起,但我对这个问题的答案很感兴趣。在英语中他们说“woof”,其实他们不说,但这是我们用来比喻猫的“喵”和牛的“moo”的词。“哈”是西班牙语吗?@JeremyP我肯定波兰狗会这么说;)@JeremyP是的,我确认狗用西班牙语说“Jau”,用英语写时是“Hau”:)这个指令有python 3的等价物吗?除了dunder方法。这个答案对实现接口类没有帮助,而接口类是使用虚拟方法的主要原因之一。
2
Traceback (most recent call last):
File "./a.py", line 13, in <module>
Base().usesVirtualMethod()
File "./a.py", line 6, in usesVirtualMethod
return self.virtualMethod() + 1
File "./a.py", line 4, in virtualMethod
raise NotImplementedError()
NotImplementedError
class A:
def prop_a(self):
return 1
def prop_b(self):
return 10 * self.prop_a()
class B(A):
def prop_a(self):
return 2
>>> B().prop_b()
20
>>> A().prob_b()
10
class A:
def __prop_a(self):
return 1
def prop_b(self):
return 10 * self.__prop_a()
class B(A):
def __prop_a(self):
return 2
>>> B().prop_b()
10
>>> A().prob_b()
10