我还不习惯在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实例调用参数a
和b
,以便我可以直接编写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类?
答案 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在属性数量方面没有限制,但你可以通过断言或我想到的东西来确保这一点。