【问题标题】:How can I further shorten this Python script which copies the contents of one file to another file?如何进一步缩短将一个文件的内容复制到另一个文件的 Python 脚本?
【发布时间】:2012-07-21 16:55:31
【问题描述】:

我正在阅读 Zed Shaw 的“Learn Python The Hard Way”。我要练习 17 次(http://learnpythonthehardway.org/book/ex17.html),并在额外的积分 2 和 3 上碰壁。Zed 希望我通过消除任何不必要的东西来缩短脚本(他声称他可以让它运行脚本中只有一行)。

这是原始脚本...

from sys import argv
from os.path import exists

script, from_file, to_file = argv

print "Copying from %s to %s" % (from_file, to_file)

# we could do these two on one line too, how?
input = open(from_file)
indata = input.read()

print "The input file is %d bytes long" % len(indata)

print "Does the output file exist? %r" % exists(to_file)
print "Ready, hit RETURN to continue, CTRL-C to abort."
raw_input()

output = open(to_file, 'w')
output.write(indata)

print "Alright, all done."

output.close()
input.close()

这就是我能够将脚本缩短到并仍然让它正常运行的内容(正确的意思是脚本成功地将预期的文本复制到预期的文件)...

from sys import argv
from os.path import exists

script, from_file, to_file = argv

input = open (from_file)
indata = input.read ()

output = open (to_file, 'w')
output.write (indata)

我摆脱了打印命令和两个关闭命令(如果我错误地使用了“命令”,请原谅......我对编码非常陌生,还没有掌握行话)。

我尝试进一步缩短脚本的任何其他内容都会产生错误。例如,我尝试将“input”和“indata”命令组合成一行……

input = open (from_file, 'r')

然后我将脚本中的所有“indata”引用更改为“input”...

from sys import argv
from os.path import exists

script, from_file, to_file = argv

input = open (from_file, 'r')

output = open (to_file, 'w')
output.write (input)

但我得到以下类型错误...

new-host:python Eddie$ python ex17.py text.txt copied.txt
Traceback (most recent call last):
  File "ex17.py", line 10, in <module>
    output.write (input)
TypeError: expected a character buffer object

您将如何进一步缩短脚本...或将其缩短为仅一行,就像 Zed 建议的那样?

【问题讨论】:

  • 我认为如果您可以发布您的代码的当前副本并就错误和优化寻求帮助会更有帮助。跨度>
  • 练习的重点是减少到一行?由于您正在复制文件,因此只需使用copy
  • 谢谢@arxanas...不知道有作业标签。
  • 感谢@Levom 的建议...在以后的问题中会记住它。

标签: python


【解决方案1】:

您可以只使用 shutil 库并让操作系统承担副本的负担(而不是在 Python 中读取/写入数据)。

import shutil
shutil.copy('from_file', 'to_file_or_directory_name')

【讨论】:

    【解决方案2】:
    from sys import argv
    open(argv[2], 'w').write(open(argv[1]).read())
    

    大概是你能得到的那样短。您可以使用分号将它们连接成一行,但这只是将行尾字符替换为其他字符,并没有真正的用处。

    【讨论】:

    • 谢谢。我试过了,效果很好。我希望我可以说我完全理解它,但我没有。我明白了一般的想法,但是你如何格式化代码行让我全都“嗯?”。可能是因为我在 Python 教程中还没有走得太远,还没有看到类似的例子。
    • “……并没有真正的用处”。正确,而且绝对不是 Pythonic。
    • 哇...看起来您编辑了答案。那个也有效……还是半“嗯?”不过。
    • @Eddie 这个想法是 infile 上的 open().read() 返回一个字符串,该字符串立即传递给 outfile 上的 open().write()。它与您编写的代码相同,除了将变量的引用替换为这些变量将被分配的实际值。例如,它将output = open();output.write() 替换为open().write()。不过,请不要对此变得聪明!代码是供人们阅读的。如果临时变量使您的意图更清晰,请使用一个!把所有东西都塞进一个高深莫测的代码球里并没有什么好处。
    • @holdenweb 我不知道我用过“;”组合线条。我仍然在精神上将这些事件视为两条单独的行,格式难看。
    【解决方案3】:

    你得到的当前错误是由于这个:

    input = open (from_file, 'r')
    
    output.write (input)
    

    write() 想要一个字符串作为参数,你给它一个文件对象。

    此外,由于您正在尝试消除冗余内容/缩短代码,小项目,opening 文件的默认模式是'r'ead,因此在打开文件进行读取时不必指定该模式。

    还可以考虑使用with 构造来打开和管理您的文件。优点是当您完成或遇到异常时,文件会自动为您关闭,因此不需要显式的close()。例如,

    with open('data.txt') as input:
       ## all of your file ops here
    

    PEP08 -- Style Guide for Python(Python 程序员的“必读”)暗示函数和开头的( 之间没有空格。

    我不确定单行的目标是否总是会产生更好或更易读的解决方案,因此应牢记这一点。

    【讨论】:

    • 谢谢...风格指南会派上用场。将阅读。
    【解决方案4】:

    不确定这是否是作者正在寻找的,但这是我经过多次试验和错误运行后提出的解决方案。我自己是初学者,所以请记住这一点。 这是脚本:

                   from sys import argv; script, from_file, to_file = argv
                   in_file = open(from_file).read(); out_file = open(to_file, 'w').write(in_file)
    

    【讨论】:

      【解决方案5】:

      我从字面上理解了“in one line”指令,并完全省略了导入行。 我也觉得它更友好:

      open(raw_input("To file? "), "w").write(open(raw_input("From file? ")).read())
      

      仍然没有关闭“到文件”,但是,嘿,一行!

      --编辑-- 我刚刚注意到,Python 确实 在脚本完成时关闭了“To file”。 所以,是的,一行!

      【讨论】:

        【解决方案6】:

        下面的呢?以为这样就可以了。

        open(input(),'w').write(open(input()).read())
        

        【讨论】:

          【解决方案7】:

          这是我想出的(也是初学者):

              from sys import argv
          
              script, from_file, to_file = argv
          
              open(to_file, 'w').write(from_file)
          

          它有效,但我不确定我是否打开了任何文件。我想我可能还需要 close() 命令。

          【讨论】:

            猜你喜欢
            • 2016-03-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-09-02
            • 1970-01-01
            • 2013-04-26
            • 1970-01-01
            相关资源
            最近更新 更多