Вы можете сделать нужный звонок, используя синтаксис
Base.Foo(self)
в вашем случае:
class Base(object):
# snipped
def Bar(self):
Base.Foo(self) # this will now call Base.Foo regardless of if a subclass
# overrides it
# snipped
x = Composite()
x.Foo() # executes Mixin.Foo, perfect
x.Bar() # prints "Base.Foo"
Это работает, потому что Python выполняет вызовы связанных методов вида
instance.method(argument)
как если бы они были вызовом несвязанного метода
Class.method(instance, argument)
поэтому вызов в этой форме дает желаемый результат. Внутри методов self
является просто экземпляром, для которого был вызван метод, то есть неявным первым аргументом (это явный параметр)
Обратите внимание, что если подкласс переопределяет Bar
, то вы ничего не можете сделать с этим, AFAIK. Но именно так все и работает в python.