允许从类B调用属于类A的方法m()

时间:2013-11-25 20:23:53

标签: python class

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

这将是这样的:

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中吗?

2 个答案:

答案 0 :(得分:6)

你可以使用mixin类:

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

class classA(MixIn): pass

class classB(MixIn): pass

请注意,使用mixins适用于小型项目,但它们无法很好地扩展到大型项目。请参阅Mixins considered harmful (part 1)(part2)(part3)(part4)。这些文章指出了一些问题,包括:

  • 命名空间污染
  • 关注点分离不足
  • 关于姓名冲突的脆弱性
  • MRO的并发症
  • 设计的不可扩展性
  • 与isa关系的概念混淆

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

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

因此,使用polymorphic functions可能会满足您的需求:

def m(self): pass

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

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

随着项目的增长,如果m的行为取决于其参数的类型,则可以使用generic functions扩展m而无需更改语法(另请参阅{ {3}})。

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

答案 1 :(得分: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

这可能不像其他人提出的mixin那样干,但它确实使你的继承树完全分开。