我对编程很新,还在学习我的绳索。如果这个问题过于简单,请道歉。
我觉得澄清我的问题有点困难,所以这里是我想要完成的一个例子:假设a是X类的一个实例,并且应该具有属性a1,a2,a3,b1,b2, b3,c1,c2和c3。我想将a1到a3,b1到b3和c1到c3放到它们自己的嵌套在X下的类A,B,C中以便于使用。这样做的正确语法是什么?
class X:
def __init__ (self, name, A, B, C):
self.name = name
self.A = A
self.B = B
self.C = C
class A (X):
def _init_ (self, name, a1, a2, a3):
self.name = name
self.a1 = a1
self.a2 = a2
self.a3 = a3
class B (x):
def _init_ (self, name, b1, b2, b3):
self.name = name
self.b1 = a1
self.b2 = a2
self.b3 = a3
class C (X):
def _init_ (self, name, c1, c2, c3):
self.name = name
self.c1 = a1
self.c2 = a2
self.c3 = a3
由于这完全是基于猜测而构建的,我99.9%肯定这是错的,但我不确定接下来我应该做些什么来做对。我试过搜索“嵌套类”的答案,但我找到的答案并没有真正澄清我的立场。
请在Python中解释嵌套类的正确语法。
感谢您的帮助,以及对此基本问题的道歉。
编辑:我的代码中有一些重要的拼写错误我刚刚纠正过。对于给您带来的任何不便,我深表歉意。答案 0 :(得分:2)
嵌套类只是其定义存在于另一个范围内的类。它们通常在Python中并不是那么有用。但是,它可以做你想要的,并从许多类中获得一个类的属性;两个主要方法是 mixins / multiple inheritance 和 composition 。
mixin方法是这样的:
class A(object):
def __init__(self, a=None, *args, **kwargs):
self.a = a
super(A, self).__init__(*args, **kwargs)
class B(object):
def __init__(self, b=None, *args, **kwargs):
self.b = b
super(B, self).__init__(*args, **kwargs)
class X(A, B):
def __init__(self, *args, **kwargs):
super(X, self).__init__(*args, **kwargs)
x = X(a='foo', b='bar')
print x.a, x.b
由于X
要具有A
和B
的属性,我们会继承它们:class X(A, B)
。
每个__init__
接受*args, **kwargs
作为参数;我们在super()
中的X
电话会将命名参数传递给A
和B
的初始化者,因此我们需要它能够接受(然后忽略)<的参数em>其他初始化者。也就是说,我们将a
和b
都传递到A.__init__
,但只使用a
。
阅读super()
对理解Python的继承至关重要。
但是,多次继承可能很难通过简单的示例进行管理,因此通常建议您改为使用 composition :
class A(object):
def __init__(self, a):
self.a = a
class B(object):
def __init__(self, b):
self.b = b
class X(object):
def __init__(self, a, b):
self.A = A(a)
self.B = B(b)
x = X('foo', 'bar')
print x.A.a, x.B.b
您可以看到这消除了super()
调用的需要以及初始化器上的任何特殊参数处理,使其更加清晰。这里我们采用两个参数,然后在内部构造相关的类并将它们附加到X
实例。这使得属性查找更加尴尬,但有一些方法可以简化:
class X(object):
# <etc>
@property
def a(self):
return self.A.a
也可以覆盖__getattr__
并进行一些动态查找,而不是手动编码每个属性。
class X(object):
# <etc>
def __getattr__(self, item):
for component in (getattr(self, c) for c in ['A', 'B']):
if hasattr(component, item):
return getattr(component, item)
另一个选择是自己传递组合实例:
class X(object):
def __init__(self, A, B):
self.A = A
self.B = B
x = X(A('foo'), B('bar'))
print x.A.a, x.B.b
这消除了X
除了接口之外对A
和B
一无所知的任何需求。这使封装更容易:如果合适,您现在可以将A
和B
粘贴到自己的模块中。为方便起见,您还可以使用工厂功能:
def make_X(a, b):
return X(
A(a),
B(b)
)
答案 1 :(得分:1)
你正在寻找继承。
另外,我注意到你错过了python是区分大小写的。这意味着a
和A
不是同一个变量
class X:
def __init__ (self, name, a, b, c):
self.name = name
self.a = a
class A (X):
def _init_ (self, name, a1, a2, a3):
self.name = name
self.a1 = a1
self.a2 = a2
self.a3 = a3
class B (A):
def _init_ (self, name, a1, a2, a3):
self.name = name
self.b1 = a1
self.b2 = a2
self.b3 = a3
class C (A):
def _init_ (self, name, a1, a2, a3):
self.name = name
self.c1 = a1
self.c2 = a2
self.c3 = a3
希望这有帮助