如果我检查列表的成员资格而不是csv.reader对象,我会得到不同的结果.以下使用unittest模块.
csv.reader测试会员资格
with open("file.tab", 'rb') as f:
reader = csv.reader(f, delimiter='\t')
self.assertTrue(['1', '2', '3', '4'] in reader)
self.assertTrue(['2', '3', '4', '5'] in reader)
self.assertTrue(['3', '4', '5', '6'] in reader)
Run Code Online (Sandbox Code Playgroud)
列出成员资格测试
with open("file.tab", 'rb') as f:
reader = csv.reader(f, delimiter='\t')
reader = [record for record in reader]
self.assertTrue(['1', '2', '3', '4'] in reader)
self.assertTrue(['2', '3', '4', '5'] in reader)
self.assertTrue(['3', '4', '5', '6'] in reader)
Run Code Online (Sandbox Code Playgroud)
我知道file.tab包含我正在测试的三条记录的条目,但第三个断言在使用csv.reader时出现"False is true",并在使用列表时传递.
csv.reader是一个生成器; 该文档没有明确说,但因为我可能会耗尽它,我认为这意味着它是一台发电机.我的想法是这可能是原因,但以下测试只打印出真实的内容:
x = xrange(5)
for m in range(5):
for n in range(5):
print m in x
print n in x
Run Code Online (Sandbox Code Playgroud)
这让我觉得测试发电机的会员资格没有问题.
为什么第三个断言语句在使用csv.reader时的评估方式与使用列表时的评估方式不同?
你在那里运气不好 - xrange实际上并不是一个发电机,而是一种特殊类型的自己,它表现得懒散,所以可以欺骗你以为它是一个.
>>> x = xrange(10)
>>> 5 in x
True
>>> 5 in x
True
Run Code Online (Sandbox Code Playgroud)
但
>>> it = iter(range(10))
>>> 5 in it
True
>>> 5 in it
False
Run Code Online (Sandbox Code Playgroud)
所以你的逻辑是对的:reader实例可能会耗尽,但列表不能,这就是为什么成员资格测试可以返回不同的答案,具体取决于内容.请注意,成员资格测试可能会短路,因此如果出现正面结果,则不必耗尽:
>>> it = iter(range(10))
>>> 3 in it
True
>>> next(it)
4
Run Code Online (Sandbox Code Playgroud)