繁体   English   中英

Python中的嵌套类

[英]nested classes in 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'

代码中的问题在哪里? 两种情况下看来,当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类的class属性,而不是您可能想要的CA 为此你必须这样做:

C.A.a = 'a_b'

此外,如果在子类中覆盖它们,Python将不会调用父方法。 你必须自己做。

范围规则意味着如果您想在CB__init__调用父类的__init__方法,它必须如下所示:

C.A.__init__(self)

而不是这样的:

A.__init__(self)

这可能是你尝试过的。

即使被认为是工厂,嵌套类看起来也是如此简单。 但回答你的问题:根本没有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定义执行中的 pythons整洁功能有关(AFAIK)。

原因相同:

def method(lst = []):

几乎是一个坏主意。 deafult参数在定义时被绑定,并且每次调用方法时都不会生成新的list-object,而是重用相同的list-object。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM