Python unittest 模块关于对象的类属性和实例属性的异常现象
在编写模块的过程中,我写到以下类和方法(这里用 A
,B
抽象表示):
class A:
pass
class B:
prop_list = [None]
def __init__(self):
self.a = A()
self.prop_list[0] = self.a
作用就是类 B
的属性 a
是 A
的一个实例,而 B.prop_list
中包含这个实例。
然后写单元测试的时候,写了如下测试(简化模型):
import unittest
class TestFirst(unittest.TestCase):
b = B()
assert b.prop_list[0] is b.a
def test_func1(self):
assert self.b.prop_list[0] is self.b.a
unittest.main()
作用就是判断 B
的实例 b
中的属性 a
就是它 prop_list
中的 a
,测试通过
但是当我添加一个一模一样的测试时候:
import unittest
class TestFirst(unittest.TestCase):
b = B()
assert b.prop_list[0] is b.a
def test_func1(self):
# !!! AssertionError
assert self.b.prop_list[0] is self.b.a
class TestSecond(unittest.TestCase):
b = B()
assert b.prop_list[0] is b.a
def test_func1(self):
assert self.b.prop_list[0] is self.b.a
unittest.main()
却发现 AssertionError
!
我尝试利用 print
函数把每个属性打印出来:
class TestFirst(unittest.TestCase):
b = B()
print('test_1:')
print(b.a)
print(b.prop_list[0])
# assert b.prop_list[0] is b.a
def test_func1(self):
print('func1:')
print(self.b.a)
print(self.b.prop_list[0])
# assert self.b.prop_list[0] is self.b.a
class TestSecond(unittest.TestCase):
b = B()
print('test_2:')
print(b.a)
print(b.prop_list[0])
# assert b.prop_list[0] is b.a
def test_func2(self):
print('func2')
print(self.b.a)
print(self.b.prop_list[0])
# assert self.b.prop_list[0] is self.b.a
得到以下结果:
test_1:
<__main__.A object at 0x000001F07CD7D7F0>
<__main__.A object at 0x000001F07CD7D7F0>
test_2:
<__main__.A object at 0x000001F07CD7D828>
<__main__.A object at 0x000001F07CD7D828>
func1:
<__main__.A object at 0x000001F07CD7D7F0>
<__main__.A object at 0x000001F07CD7D828> // 这里居然不是 0x000001F07CD7D7F0
.func2
<__main__.A object at 0x000001F07CD7D828>
<__main__.A object at 0x000001F07CD7D828>
.
----------------------------------------------------------------------
Ran 2 tests in 0.002s
- 为什么
TestFirst
实例方法test_func1
中self.b.prop_list[0]
和自己的self.b.a
不是同一个对象,而和TestSecond
实例方法test_func2
中的self.b.prop_list[0]
一样呢?
另外,如果我把 class B
的 prop_list
当作实例属性,在初始化函数 __init__()
中声明:
class A:
pass
class B:
def __init__(self):
self.a = A()
self.prop_list= [self.a]
再次运行上述测试时候,发现可以通过。
这两种方式为什么会有差别,这里面还有其他坑没有?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是這樣的:
這裡從頭到尾的
prop_list
都是同一個!所以
TestSecond
中b
被初始化的時候, 就將prop_list[0]
的值設定為TestSecond
中b.a
的值了, 而test_func1
又在之後被調用, 此時prop_list[0]
的值自然跟TestFirst
中b.a
的值不同, 而是與TestSecond
中的b.a
相同。補充一下, 為什麼
prop_list
為什麼都是同一個呢, 因為他是B
的類別屬性, 會自然成為每個B
實例的屬性, 而且他從頭到尾沒有在任何B
的實例中被重新賦值過(他的第零個元素prop_list[0]
倒是有被重新賦值過), 所以他 always 是同一個人。我回答過的問題: Python-QA