16

只是关于 python 和 .join() 方法的一个基本问题:

file1 = open(f1,"r")
file2 = open(f2,"r")
file3 = open("results","w")

diff = difflib.Differ()
result = diff.compare(file1.read(),file2.read())
file3.write("".join(result)),

上面的代码片段产生了一个很好的输出,以字符串格式存储在一个名为“results”的文件中,逐行显示了两个文件之间的差异。但是我注意到,如果我只打印“结果”而不使用 .join(),编译器会返回一条包含内存地址的消息。在尝试不使用 .join()将结果写入文件后,编译器通知我在 .join() 方法中只能使用字符串和字符缓冲区,而不是生成器对象。因此,根据我引用的所有证据,如果我错了,请纠正我:

  1. result = diff.compare(file1.read(),file2.read()) <---- 结果是生成器对象?

  2. result是一个字符串列表,result它本身就是对第一个字符串的引用?

  3. .join()获取一个内存地址并指向第一个,然后遍历该结构中字符串的其余地址?

  4. 生成器对象是返回指针的对象吗?

如果我的问题不清楚,我很抱歉,但我基本上是想问问蟒蛇老兵我的推论是否正确。我的问题不是关于可观察的结果,而是关于 python 的内部工作原理。我感谢您的所有帮助。

4

1 回答 1

37

join是一种字符串方法。该方法采用任何可迭代对象并对其进行迭代并将内容连接在一起。(内容必须是字符串,否则会引发异常。)

如果您尝试将生成器对象直接写入文件,您将只获取生成器对象本身,而不是其内容。 join“展开”生成器的内容。

你可以看到一个简单的、显式的生成器发生了什么:

def gen():
    yield 'A'
    yield 'B'
    yield 'C'

>>> g = gen()
>>> print g
<generator object gen at 0x0000000004BB9090>
>>> print ''.join(g)
ABC

生成器一次分发一个内容。如果您尝试查看生成器本身,它不会释放任何东西,您只会将其视为“生成器对象”。要获取其内容,您需要遍历它们。您可以使用for循环、next函数或迭代事物(str.join其中包括)的任何其他各种函数/方法来执行此操作。

当您说结果“是字符串列表”时,您就接近了这个想法。生成器(或可迭代的)有点像“潜在列表”。它不是一次真正成为所有内容的列表,而是让您一次剥离每个项目。

没有一个对象是“内存地址”。生成器对象的字符串表示形式(与许多其他对象一样)包括一个内存地址,因此如果您将其打印(如上)或将其写入文件,您将看到该地址。但这并不意味着对象“是”那个内存地址,并且地址本身并不是真正可用的。它只是一个方便的识别标签,因此如果您有多个对象,您可以将它们区分开来。

于 2013-01-21T20:59:04.890 回答