首页 > 解决方案 > 我可以在 __init__ 函数中有条件地从一组固定的父类中选择一个类的父类吗?

问题描述

我有一个子班,有两个父母具有相同的函数名称。

我需要在构造函数 () 中决定(基于正在创建的对象的类型)__init__子对象需要调用哪个父类的函数。有没有办法将默认函数调用动态链接/切换到其中一个父母的调用。下面给出的示例代码。我不想使用容器的对象,因为它很难维护和重构。

class Square: 
 def perform(self, num):
     print(num * num)

class Cube: 
 def perform(self, num):
     print(num * num * num)

class Exponent(Square, Cube):
 def __init__(self, type):
    if type == 'square':
        # inherit default functions from square <--- ??
    else:
        # inherit default functions from cube <--- ??

    square = Square()  # <-- i don't want to do this
    cube = Cube()      # <-- i don't want to do this

Exponent('cube').perform(2)    # --> should print '8'
Exponent('square').perform(2)  # --> should print '4'

Exponent('cube').cube.perform(2)      # <-- i don't want to do this
Exponent('square').square.perform(2)  # <-- i don't want to do this

下面给出了一种方法,但涉及复制所有父类函数,这太过分了:

class a:
    def x (self):
        print('a')

class b:
    def x (self):
        print('b')

class c(a,b):
    def __init__(self, type_):
        if type_ == 'a':
            self.ref = a
        else:
            self.ref = b

    def x(self):
        self.ref.x(self)


c('a').x()
c('b').x()

标签: pythonpython-3.x

解决方案


Python 提供了很大的灵活性,但是您正在使用该语言提供的类机制。“没有任何额外的努力”是没有办法做到这一点的,因为您将在语言提供的基础上实现自己的机制。老实说,忘记使用多重继承,因为继承不是您所描述的,您需要一个代理对象来委托给适当的对象。根据您的具体情况,这可能会有所不同,但这会让您继续前进:

In [1]: class A:
   ...:     def x (self):
   ...:         print('a')
   ...:
   ...: class B:
   ...:     def x (self):
   ...:         print('b')
   ...:
   ...: class C:
   ...:     def __init__(self, type_, *args, **kwargs):
   ...:         self.__wrapped = type_(*args, **kwargs)
   ...:     def __getattr__(self, attr):
   ...:         return getattr(self.__wrapped, attr)
   ...:
   ...:

In [2]: C(A).x()
a

In [3]: C(B).x()
b

注意,C.__init__实现的方式是,第一个参数之后的所有内容都传递给委托类型的构造函数。


推荐阅读