【问题标题】:The output of multiple classes calling functions from different classes多个类调用不同类的函数的输出
【发布时间】:2020-02-06 15:39:45
【问题描述】:

我正在尝试理解以下代码,我需要在其中确定将要打印的输出。但是,我被卡住了一半。代码(对不起,我似乎无法正确设置间距):

# Let the classes A and B be
class A:
    def __init__ (self):
        self.i = 3
    def doubled (self):
        self.i *= 2

class B:
    def __init__ (self, an_a_object):
        self.a = an_a_object
    def put (self, an_a_object):
        self.a = an_a_object

# Further we have a program with the following statements/declarationsa
a1 = A()
b1 = B(a1)
def show (an_a_object, a_b_object):
    print '%d %d' % (an_a_object.i, a_b_object.a.i)

show(a1, b1)
b1.a.doubled()
show(a1, b1)
a2 = A()
show(a2, b1)
b1.put(a2)
show(a2, b1)
b2 = B(a1)
show(a1, b1)
b2.a.doubled()
show(a2, b2)
b1.a.doubled()
b2.put(b1.a)
show(a2, b2)

这个程序会打印什么?

所需的输出: 3 3

6 6

3 6

3 3

6 3

3 12

6 6

我直到 6 3 才明白,但在那之后我不明白。我认为 b2.a.doubled() 会使 b2 加倍(我认为在加倍之前是 3,因为 b2 = B(a1)),但显然 b2 在加倍时是 12?而且我认为a2也会加倍,但a2仍然是3?那为什么在第一个 b1.a.doubled() 之后,a1 和 b1 都加倍(因为它从 3 3 变为 6 6)?

【问题讨论】:

  • 请修正你的缩进。
  • 另外,请阅读nedbatchelder.com/text/names.htmlself.a = an_a_object 不会复制 A 对象。 ab.a 都引用同一个 mutable 对象。通过一个引用所做的更改可以通过另一个看到。

标签: python python-2.7 function class reference


【解决方案1】:

我认为 b2.a.doubled() 会使 b2 加倍

正确。

(翻倍前我以为是3,

不正确。是 6

因为 b2 = B(a1)),

a1 是 6,因为它在 b1.a.doubled() 行中翻了一番

正如切普纳所说,

通过一个引用所做的更改通过另一个引用可见。

【讨论】:

  • 进一步 a2 仅通过 'a2 = A()' 初始化并在 b1 ('b1.put(a2)') 中引用。 a2 或 b1 都没有在任何地方加倍 -> a2 保持 3
  • 感谢您的回答。为什么在第一个 double 中,b1.a.doubled() 中,a1 和 b1 都加倍,但在 b2.a.doubled() 中,只有 b2 加倍,而不是 a2?
  • 在第一个双精度 b1 中使用 a1 作为参数进行初始化。 a1 和 b1 都持有对同一个对象(!)的引用。 b2 与 a2 没有任何关系(仅通过对象名称,这可能会造成混淆)。
【解决方案2】:

标识正确的代码:

class A:
    def __init__(self):
        self.i = 3

    def doubled(self):
        self.i *= 2


class B:
    def __init__(self, an_a_object):
        self.a = an_a_object

    def put(self, an_a_object):
        self.a = an_a_object


def show(an_a_object, a_b_object):
    print '%d %d' % (an_a_object.i, a_b_object.a.i)


a1 = A()
b1 = B(a1)
show(a1, b1)
b1.a.doubled()
show(a1, b1)
a2 = A()
show(a2, b1)
b1.put(a2)
show(a2, b1)
b2 = B(a1)
show(a1, b1)
b2.a.doubled()
show(a2, b2)
b1.a.doubled()
b2.put(b1.a)
show(a2, b2)

class B 内部,self.a 指的是通过调用A() 创建的同一对象。修改a 与修改b.a 相同,并且两个实例将具有相同的值。

由于许多具有相似名称的变量,此代码难以阅读。我建议您使用更明确的名称,以便于阅读。

【讨论】:

    【解决方案3】:

    打印所有结果并进行分析会很有趣。我为 A 类和 B 类更改了 __repr__ 函数,因此我们可以在每次操作之间轻松打印它们。我在每个“打印”行之间添加了输出。

    class A:
        def __init__ (self):
            self.i = 3
    
        def doubled (self):
            self.i *= 2
    
        def __repr__ (self):
            return str(self.i)
    
    class B:
        def __init__ (self, an_a_object):
            self.a = an_a_object
    
        def put (self, an_a_object):
            self.a = an_a_object
    
        def __repr__ (self):
            return str(self.a.i)
    
    a1 = A()
    b1 = B(a1)
    a2 = None
    b2 = None
    
    def show():
        print("a1 =", a1, ", a2 =", a2, ", b1 =", b1, ", b2 =", b2)
    
    show()
    # a1 = 3 , a2 = None , b1 = 3 , b2 = None
    
    b1.a.doubled()
    show()
    # a1 = 6 , a2 = None , b1 = 6 , b2 = None
    
    a2 = A()
    show()
    # a1 = 6 , a2 = 3 , b1 = 6 , b2 = None
    
    b1.put(a2)
    show()
    # a1 = 6 , a2 = 3 , b1 = 3 , b2 = None
    
    b2 = B(a1)
    show()
    # a1 = 6 , a2 = 3 , b1 = 3 , b2 = 6
    
    b2.a.doubled()
    show()
    # a1 = 12 , a2 = 3 , b1 = 3 , b2 = 12
    
    b1.a.doubled()
    show()
    # a1 = 12 , a2 = 6 , b1 = 6 , b2 = 12
    
    b2.put(b1.a)
    show()
    # a1 = 12 , a2 = 6 , b1 = 6 , b2 = 6
    
    

    【讨论】:

      猜你喜欢
      • 2019-04-08
      • 2016-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多