Python继承:将所有参数从base传递给超类

时间:2015-08-24 15:00:48

标签: python inheritance

我还不习惯在Python中继承类继承。我想要做的就是在创建时将所有参数从我的基类传递给超类:

class A:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def do(self):
        c = self.a + self.b
        return B(c=c)

class B(A):
    def __init__(self, c):
        self.c = c

my_A = A(a=1, b=2)
my_B = my_A.do()
print(my_B.c)

这可以按预期工作。但是,我想要的是也能够从类my_B的x2实例调用参数ab,以便我可以直接编写my_B.a。我知道这是用super()完成的:

class A:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def do(self):
        c = self.a + self.b
        return B(a=self.a, b=self.b, c=c)

class B(A):
    def __init__(self, a, b, c):
        super(B, self).__init__(a=a, b=b)
        self.c = c

my_A = A(a=1, b=2)
my_B = my_A.do()
print(my_B.a)
print(my_B.b)

但是,当我创建B的实例时,我不想显式地写出A的所有参数。有没有办法自动将所有参数从A类传递给B类?

3 个答案:

答案 0 :(得分:2)

根据您的评论,您可以执行以下操作:

class B(A):
    def __init__(self, c, an_a): 
        super(B, self).__init__(an_a.a, an_a.b)
        self.c = c

您可能更愿意保留当前的构造函数并添加from_a静态方法:

class B(A):
    def __init__(self, c, a, b):  # note order
        super(B, self).__init__(a=a, b=b)
        self.c = c

    @staticmethod
    def from_a(c, an_a):
        return B(c, an_a.a, an_a.b)

最后,如果您不想输入所有这些参数,可以向args()添加A方法,然后使用集合解包函数语法:

class A:
    ...
    def args(self):
        return (self.a, self.b)

class B(A):
    def __init__(self, c, *args):        # Note *args
        super(B, self).__init__(*args)
        self.c = c

    @staticmethod
    def from_a(c, an_a):
        return B(c, *an_a.args())

现在B的构造函数将参数特殊赋予B,后跟任意数量的参数,这些参数只传递给A的构造函数。这允许您在调用构造函数时执行元组解包,而不是手动列出所有内容。

答案 1 :(得分:0)

好的,谢谢你的评论。我想出了这个解决方案:

class A:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def do(self):
        c = self.a + self.b
        return B(self, c)

class B:
    def __init__(self, base, c):
        self.base = base
        self.c = c

my_A = A(a=1, b=2)
my_B = my_A.do()
print(my_B.base.a)
print(my_B.base.b)
print(my_B.c)

这删除了B类的继承并使代码的可读性略低,但我猜它会这样做,对吧?

答案 2 :(得分:0)

是的,有一种方法可以使用关键字参数:

class A(object):
    def __init__(self,**kwargs):
        # Non pythonic and a bit of a hack
        self.kwargs = kwargs
        vars(self).update(kwargs)

    def do(self):
        c = self.a + self.b
        return B(c=c, **kwargs)

class B(A):
    def __init__(self, c, **kwargs):
        self.c = c
        super(B, self).__init__(**kwargs)

my_A = A(a=1, b=2)
my_B = my_A.do()
print(my_B.a)
print(my_B.b)
print(my_B.c)

这就是你所做的事情,无论以前写的方式是多少pythonic运行时应该输出:

1
2
3

这样做的缺点是,现在A在属性数量方面没有限制,但你可以通过断言或我想到的东西来确保这一点。