在python中处理类(嵌套等)并不容易,令人惊讶!我最近发现了以下问题,花了几个小时(尝试,搜索…)都没有成功。我阅读了大部分相关链接,但没有一个链接指出了这里提出的问题!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46#------------------------------------
class A:
def __init__(self):
self.a = 'a'
print self.a
class B(A):
def __init__(self):
self.b = 'b'
A.a = 'a_b'
print self.b, A.a
#------------------------------------
class C:
class A:
def __init__(self):
self.a = 'a'
print self.a
class B(A):
def __init__(self):
self.b = 'b'
A.a = 'a_b'
print self.b, A.a
#------------------------------------
#------------------------------------
>>> c1 = A()
a
>>> c1.a
'a'
>>> c2 = B()
b
>>> c2.a, c2.b
('a_b', 'b')
>>> c3 = C()
>>> c4 = c3.A()
a
>>> c4.a
'a'
>>> c5 = c3.B()
b a_b
>>> c5.b
'b'
>>> c5.a
Traceback (most recent call last):
File"", line 1, in
AttributeError: B instance has no attribute 'a'
代码中的问题在哪里?和在这两种情况下,当B(A)初始化时,A()似乎没有初始化。这个问题的解决方案是什么?注意,在b()的__init__()中调用的术语A.__init__()不起作用!
更新:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class Geometry:
class Curve:
def __init__(self,c=1):
self.c = c #curvature parameter
print 'Curvature %g'%self.c
pass #some codes
class Line(Curve):
def __init__(self):
Geometry.Curve.__init__(self,0) #the key point
pass #some codes
g = Geometry()
C = g.Curve(0.5)
L = g.Line()
结果是:
1
2Curvature 0.5
Curvature 0
我在找什么。
"……"在b()的__init__()中被调用的A.__init__()不起作用!"否则就不会发生。
同上。你在B.__init__()的A.__init__()电话是什么样子的?
@伊格纳西奥瓦兹·艾布拉姆斯找到了解决问题的方法。几小时后就好了。你可以在问题的更新部分找到你的观点。
@请看我对伊格纳西奥·瓦兹奎兹·艾布拉姆斯的评论。
@如果您不创建外部几何体类,而是创建一个名为"几何体"的模块,那么它会简单得多。然后得到完全相同的分组,但没有嵌套类的复杂性:import geometry as gc = g.Curve(0.5)l = g.Line()。
@邓肯有用的小费。谢谢。
方法中执行的代码在该方法的本地范围内运行。如果您访问的对象不在此范围内,python将在全局/模块范围内查找它,而不在类范围或任何封闭类的范围内!
这意味着:
1A.a = 'a_b'
在C.B.__init__中,将设置全局A类的类属性,而不是您可能想要的C.A类属性。为此,你必须这样做:
1C.A.a = 'a_b'
另外,如果您在子类中重写父方法,Python也不会调用它们。你得自己动手。
作用域规则意味着,如果要调用C.B.__init__中父类的__init__方法,则必须如下所示:
1C.A.__init__(self)
而不是这样:
1A.__init__(self)
这可能是你尝试过的。
谢谢。我可以用你的要点来解决这个问题。完整的解决方案已作为更新添加。
嵌套类看起来很不实用,即使被认为是工厂。但要回答你的问题:根本就没有C5.A(C.B的例子)。在C.B的init方法中,您向C.A类添加了一个属性A,但不添加到C.B!如果实例化,类A已经有了属性A!但是B类(甚至是B类)的对象没有!
您还必须记住,EDCOX1 0是不是像C++或Java那样的构造函数!python中的"真正的构造函数"是__new__。__init__只是初始化类的实例!
1
2
3
4class A:
c = 'class-attribute'
def __init__(self):
self.i = 'instance-attribute'
所以在这个例子中,c是一个类属性,其中i是实例的一个属性。
更有趣的是,您试图在子类实例化时向基类添加一个属性。这样就不会得到"延迟"继承属性。您只需向类A添加一个额外的属性,这让我惊讶,甚至可以工作。我猜你用的是python 3.x?
这种行为的原因是什么?好吧,我想这和pythons的整洁特性有关,在python定义中执行(afaik)。
原因相同:
1def method(lst = []):
几乎是个坏主意。deafult参数在定义时被绑定,每次调用该方法时都不会生成新的列表对象,而是重用同一个列表对象。
谢谢你的回答。正如您在问题的更新部分所看到的,有时嵌套类使编程更结构化,更容易处理。