2013-11-25 41 views
1

我有两个类在大多数方面是不同的,但它们共享一个通用方法。我想从B类中调用此方法(它属于A类):允许调用从B类属于A类的方法m()

这将是这样的:

class classA(): 
    def m(): 
     pass 

class classB(): 


classB_instance = classB() 
classB_instance.m() #here I would like to call a method m() which belongs to class A 

我知道它可能继承ClassA的这种方法,但是我不希望在这里使用继承,因为classA具有与classB无关的其他方法。

但是,我很乐意使用“受限制的继承”。我的意思是......我只想继承这个方法,但保持其他方法/属性不变。

Python中可能吗?

+3

创建另一个类C代表“有m()”,并在A和B中继承这个类。 –

回答

6

你可以使用一个混合类:

class MixIn(object): 
    def m(self): 
     pass 

class classA(MixIn): pass 

class classB(MixIn): pass 

注意,使用混入小型项目工作正常,但他们没有很好地扩展到大型项目。见Mixins considered harmful (part 1),(part2),(part3), (part4)。这些文章指出了一些问题,其中包括:

  • 命名空间污染
  • 分离不足的担忧
  • 脆性相对于名称冲突的的MRO
  • 非可扩展性的
  • 并发症设计
  • 与伊斯兰关系的概念混淆

即使mixin对于小型项目也可以很好地工作,但如果它们不能很好地扩展,那么鼓励它们的使用并不好,因为小型项目可能会成长为大型项目(尽管作者的最佳意图是:-))。

@ mgilson的回答可能会更好,因为它的明确性避免了难以追踪/命名空间污染问题。但它仍然容易受到上述其他许多问题的影响。

所以,另一方面,使用polymorphic functions可能会满足您的需求:

def m(self): pass 

class classA(object): pass 
class classB(object): pass 

a = classB() 
b = classB() 
m(a) 
m(b) 

随着项目的发展,如果m的行为取决于它的参数的类型,可以延长m,而无需改变语法通过使用generic functions(也参见PEP443)。

另一种更好的方法是使用composition instead of inheritance。例如,请参阅interface wrapper solution

+0

FWIW,我可能会用这个答案... – mgilson

4

你可以写一个普通的功能,只是把它变成你的类的命名空间:

>>> def _m(self): 
...  print "Hello World" 
... 
>>> class Foo(object): 
...  m = _m 
... 
>>> class Bar(object): 
...  m = _m 
... 
>>> Foo().m() 
Hello World 
>>> Bar().m() 
Hello World 

这可能并不像其他人提出的混入干,但它确实让你继承树完全分开的。

相关问题