我创建了一个名为Liger
的Python类,它扩展了一个名为Lion
的类和一个名为Tiger
的类。类Liger
从Lion
和{speak()
,但是语法仍然有效-不会打印错误消息,而是,Tiger
方法的实现由Liger
继承。有没有可能在Python中检测方法名冲突,以便在方法名以这种方式冲突时打印错误消息?在
'''
Conflicting method names in python
'''
class Tiger():
@staticmethod
def speak():
print "Rawr!";
class Lion():
@staticmethod
def speak():
print "Roar!";
class Liger(Tiger, Lion):
pass
'''both superclasses define a speak() method, and I need a way to detect this type of conflict.'''
Liger.speak(); ''' this prints "Rawr" instead of printing an error message. '''
'''Is there any way to detect method name collisions like this one?'''
代码可以在这里在线测试和调试:http://ideone.com/xXOoVq
可以使用元类检测此类冲突:
这是一个非常粗糙的第一个版本,错误消息很差,每当在继承树中的
Liger
上重写一个方法时,它实际上会引发一个错误,但它应该足以让您开始。在我不确定继承是否是解决问题的正确机制。继承通常被称为定义两个类之间的“is-A”关系。也就是说,如果}的实例。在
A
从B
继承,B
的每个实例也是{如果使用多重继承,则该类最终会同时成为多种类型的对象。在您的示例中,
Liger
实例同时是Tiger
和Lion
。在您可能不想使用类继承来建模物种继承。尽管有名字,但它们的意思并不完全相同。例如,家猫可能是虎类动物的后代,但是说家猫是老虎是不对的。在
您在类上使用静态方法的事实使我认为您可能根本不想使用类,而是使用更通用的
Animal
类的实例:那里没有遗传机制,但是可以增加一种方法,以某种方式使一种动物变异成另一种动物。在
现在,如果您真的打算使用类和多重继承,有两种不错的方法(使用常规实例方法,而不是静态方法):
第一种方法是执行“协作多重继承”,并让每个方法在MRO的下一个类上调用相同的方法。通常,您需要从公共基类继承来实现这一点(否则,对
^{pr2}$super
的最后一次调用将得到object
,它没有定义方法):在这种情况下,
Liger
实例的speak
方法将同时打印Roar
,然后Rawr
,这是有意义的,因为它同时是狮子和老虎。不过,要小心这种编码方式,因为要使协作正常工作是很困难的。例如,您不能更改方法签名并期望它在协作的多重继承情况下正常工作(除非您只使用关键字参数,并且在**kwargs
中传递任何未识别的参数)。在第二个解决方案是给出
Liger
它自己的speak
实现,它显式地选择要做什么(可以调用它的一个基类)。这在某些其他语言中是必需的,比如C++。如果您请求的继承没有执行您想要的操作,那么这可能是最直接的解决方法:相关问题 更多 >
编程相关推荐