<pre><code>words = line.split('\n')
num_words += len(words)
</code></pre>
<p>并不像你想的那样。在循环中</p>
^{pr2}$
<p><code>line</code>是一个以<code>'\n'</code>结尾的字符串,因此<code>line.split('\n')</code>是一个两项列表,第一项包含除终止<code>'\n'</code>之外的行的所有字符;该列表中的第二项是空字符串。示例:</p>
<pre><code>line = 'This is a test\n'
words = line.split('\n')
print(words, len(words))
</code></pre>
<p><strong>输出</strong></p>
<pre><code>['This is a test', ''] 2
</code></pre>
<p>所以你的<code>num_words += len(words)</code>实际上并不计算单词,它只是行数的两倍。在</p>
<p>要获得<code>line</code>中单词的实际列表,您需要</p>
<pre><code>words = line.split()
</code></pre>
<p>倒数第二行</p>
<pre><code>num_charsx = num_chars - line.count(' ')
</code></pre>
<p>在<code>for</code>循环之外,因此它从总计<code>num_chars</code>中减去文件最后一行的空间计数,但我假设您确实想从<code>num_chars</code>中减去整个文件的总空间计数。在</p>
<p>这是您代码的修复版本。在</p>
<pre><code>num_words = 0
num_chars = 0
num_spaces = 0
with open(fname, 'r') as f:
for num_lines, line in enumerate(f, 1):
num_words += len(line.split())
num_chars += len(line) - 1
num_spaces += line.count(' ')
num_charsx = num_chars - num_spaces
print(num_lines, num_words, num_chars, num_spaces, num_charsx)
</code></pre>
<p>我修改了行读取循环以使用<code>enumerate</code>。这是获取行号和行内容的有效方法,而不必维护单独的行计数器。在</p>
<p>在<code>num_chars += len(line) - 1</code>中,<code>-1</code>是这样的,因此我们不在字符计数中包含每行的终止<code>'\n'</code>。在</p>
<p>请注意,在Windows上,文本文件行(通常)以<code>'\r\n'</code>结尾,但当您读取以文本模式打开的文件时,该终止符将转换为<code>'\n'</code>。所以在Windows上,文件的实际字节大小是<code>num_chars + 2 * num_lines</code>,假设最后一行有一个<code>'\r\n'</code>结束符;它可能没有,在这种情况下,实际大小将比这个小2个字节。在</p>