Python中的嵌套类
处理类(嵌套等)在Python中看起来并不简单, 令人惊讶 ! 以下问题最近出现在我身上,花了几个小时(尝试,搜索...),但没有成功。 我阅读了大部分与SO相关的链接,但他们都没有指出这里介绍的问题!
#------------------------------------ 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'
代码中的问题在哪里? AND在两种情况下,似乎当B(A)初始化时A()未初始化。 这个问题的解决方案是什么? 请注意,在B()的__init__()
中调用的术语A.__init__()
不起作用!
更新:
class 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()
这导致:
Curvature 0.5 Curvature 0
我在找什么。
在方法中执行的代码在该方法的本地范围内运行。 如果你访问一个不在这个范围内的对象,Python将在全局/模块范围内查找它,而不是在任何封闭类的范围或范围内查找!
这意味着:
A.a = 'a_b'
在CB__init__
中将设置全局A
类的类属性,而不是您想要的CA
为此,你必须这样做:
C.A.a = 'a_b'
另外,如果你在子类中覆盖它们,Python将不会调用父方法。 你必须自己做。
范围规则意味着如果您想调用CB__init__
父类的__init__
方法,它必须如下所示:
C.A.__init__(self)
而不是像这样:
A.__init__(self)
这可能是你尝试过的。
即使被视为工厂,嵌套类似乎也是如此unpythonic。 但要回答你的问题:没有c5.a(CB的实例)。 在CB的init方法中,您将CLASS CA添加到属性a,但不添加到CB! 如果实例化了类A,那么它已经有了一个属性a! 但是B类(甚至是类)的对象不是!
您还必须记住, __init__
不是像C ++或Java那样的构造函数! python中的“真正的构造函数”是__new__
。 __init__
只是初始化一个类的实例!
class A:
c = 'class-attribute'
def __init__(self):
self.i = 'instance-attribute'
所以在这个例子中,c是一个class-attribute,其中i是实例的一个属性。
更令人好奇的是,您尝试在子类的实例化时向基类添加属性。 你没有得到这样的“迟到”继承属性。 您只需向类A中添加一个额外的属性,这令我感到惊讶即使工作。 我猜你正在使用python 3.x?
这种行为的原因是什么? 那么,我想它与python定义执行(Python)中的Python特性有关。
同样的原因:
def method(lst = []):
几乎是一个糟糕的主意。 deafult参数在定义的时刻被绑定,并且每次调用方法时都不会生成新的列表对象,但会重新使用同一个列表对象。
链接地址: http://www.djcxy.com/p/53627.html