【问题标题】:How does python determine to make a new instance of an object or to use an old one?python如何确定创建对象的新实例或使用旧实例?
【发布时间】:2020-10-10 16:07:17
【问题描述】:

我想了解 python 如何确定创建对象的新实例或使用现有实例。我一直在寻找一些我认为会给我带来问题的东西,我怀疑这是因为我对幕后发生的事情缺乏了解。

在一个 dummy.py 文件中考虑这个例子:

import unittest


class Addition:

    def __init__(self, a, b):
        self.__a = a
        self.__b = b

    def do_addition(self):
        return self.__a + self.__b


class IsolatedTests(unittest.TestCase):

    def custom_add(self, a, b):
        addition = Addition(a, b)
        print(addition)
        return addition.do_addition()

    def test_case_1(self):
        a = 5
        b = 10
        self.assertEqual(15, self.custom_add(a, b))

    def test_case_2(self):
        a = 20
        b = 15
        self.assertEqual(35, self.custom_add(a, b))

    def test_case_3(self):
        a = 99
        b = 105
        self.assertEqual(204, self.custom_add(a, b))

当我打印创建的添加对象的内存位置时,我得到三个不同的位置。

<dummy.Addition object at 0x02BBBF70>    
<dummy.Addition object at 0x02BBBE20>    
<dummy.Addition object at 0x02BBBEC8>      

现在,考虑对同一事物稍作修改的版本。

class CombinedTests(unittest.TestCase):

    def custom_add(self, a, b):
        addition = Addition(a, b)
        print(addition)
        return addition.do_addition()

    def test_case_1(self):
        a = 5
        b = 10
        self.assertEqual(15, self.custom_add(a, b))
        a = 20
        b = 15
        self.assertEqual(35, self.custom_add(a, b))
        a = 99
        b = 105
        self.assertEqual(204, self.custom_add(a, b))

在这里,我实际上为添加对象的所有 3 个实例获得了相同的确切内存地址。

<dummy.Addition object at 0x02BBBF70>    
<dummy.Addition object at 0x02BBBF70>    
<dummy.Addition object at 0x02BBBF70>    

有人可以帮我理解这里有什么区别吗?一如既往的感谢!

【问题讨论】:

  • 如果两个对象具有不同的地址,则可以合理地确证它们是不同的对象。但是,如果在不同时间创建的两个对象具有相同的地址,这并不能确凿地证明它们是同一个对象。我做了一个测试,我创建了一个对象,然后删除了它,然后创建了另一个对象,两个对象都有相同的地址。如果没有足够的其他事情发生,那么无论什么导致解释器在某个地址定位 object1 都可能导致它在 object1 消失时在同一地址创建另一个对象。
  • 另外,这可能是关于 unittest 模块而不是 Python 的问题。我测试了您发布的所有单元测试部分的代码,虽然对象位于独立测试和组合测试的不同位置,但在每个位置中,地址都没有改变。
  • 我明白你在说什么,如果我只是让它们成为常规课程,也许它就是 unittest 模块。那么,在单元测试之外,这是如何工作的呢?在孤立的情况下,您会认为这是创建、销毁、创建、销毁……并且它只是继续使用相同的内存地址吗?在所有调用都在一个函数中的情况下,比如在组合中,这是否与调用堆栈有关,因此我应该期待 3 个不同的内存地址?不是所有 3 个都需要同时存在于调用堆栈上吗?
  • 在这两种情况下,每当 custom_add 函数运行时,它都会创建一个 Addition 对象,当控制离开函数时不再需要该对象。到达那里需要多少层调用没有区别。所以在没有单元测试的简单情况下,在同一地址找到所有对象也就不足为奇了。在这两种情况下都不需要同时存在三个 Addition 对象。可能在 IsolatedTests 的情况下,unittest 框架在测试之间创建了一些其他对象,因此 Addition 对象获得不同的地址。

标签: python-3.x computer-science python-unittest


【解决方案1】:

使用CombinedTests 类,在同一地址连续创建三个Addition 对象。这并不意味着它们是同一个对象。

使用 IsolatedTests 类,unittest 框架可能会在运行该类中的三个测试用例函数之间创建其他对象,因此三个 Addition 对象被创建在不同的位置。

一般来说,是程序员而不是解释器决定是创建一个新对象还是重用一个旧对象。如果你想使用一个对象,由你决定是创建一个对象还是使用你已经存在的对象。您假设报告在不同时间具有相同地址的两个对象是同一个对象,但事实并非如此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    相关资源
    最近更新 更多