python中类的嵌套_关于类:Python中的嵌套类

在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参数在定义时被绑定,每次调用该方法时都不会生成新的列表对象,而是重用同一个列表对象。

谢谢你的回答。正如您在问题的更新部分所看到的,有时嵌套类使编程更结构化,更容易处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值