【问题标题】:python file overwriting with os module使用 os 模块覆盖 python 文件
【发布时间】:2023-06-05 10:27:01
【问题描述】:

我正在编写一个程序,它将文件从一个文件夹移动到另一个文件夹。有时我会在此过程中覆盖文件。但是,每当我运行该文件时,都会询问我“覆盖 C:...(是/否/全部)”。我希望我的程序始终自动选择“全部”。提前谢谢你

import os
from tkinter import *
screen = Tk()
sourceplayers = 'C:\\Program Files (x86)\...\players' 
destinationplayers = 'C:\\memory\Will\players'
sourceuserdata = ('C:\\\\Program Files (x86)\...\remote'
destinationuserdata = 'C:\\\\memory\\Will\\remote'

def copyout(): 
    os.system ("""xcopy "%s" "%s" """ % (sourceplayers, destinationplayers)) 
    os.system ("""xcopy "%s" "%s" """ % (sourceuserdata, destinationuserdata)) #save


def movein():
    os.system ("""xcopy "%s" "%s" """ % (destinationplayers, sourceplayers))
    os.system ("""xcopy "%s" "%s" """ % (destinationuserdata, sourceuserdata))  

button = Button(screen, text="save", command=copyout)
button1 = Button(screen, text="overwrite", command=movein)
button.pack()
button1.pack()
screen.mainloop()

【问题讨论】:

    标签: python directory operating-system copy shutil


    【解决方案1】:

    那是因为您正在使用系统调用来进行移动。您可以使用os.listdir 的组合列出源文件中的所有文件和目录,并使用shutil.move 进行移动。

    【讨论】:

    • 我之前尝试使用shutil,但它不允许我从我的程序文件中复制(我很抱歉,因为我忘记在我的问题中指定这一点)。一些用户建议我添加 /y 并且它有效。无论如何,感谢您的宝贵时间。
    【解决方案2】:

    如果你不能使用标志。您可以尝试使用subprocess.Popen 写入标准输入,这应该完全符合您的要求:

    from subprocess import PIPE,Popen
    
    p = Popen(["xcopy",sourceplayers, destinationplayers],stdin=PIPE)
    p.stdin.write("All\n")
    p = Popen(["xcopy",sourceuserdata, destinationuserdata],stdin=PIPE)
    p.stdin.write("All\n")
    

    无论哪种方式,您都应该在 os.system 上使用 subprocess 模块,subprocess 是 os.popen、os.system 等的替代品。

    如果/y 适用于所有文件,请使用subprocess.check_call

    from subprocess import check_call
    
    check_call(["xcopy","/y",sourceuserdata, destinationuserdata])
    

    如果您希望在运行下一个命令之前返回上一个命令,请在每个调用之间添加一个 p.wait() 以等待进程返回。

    如果你正在替换一个文件那么你不需要在 python 之外寻找,你可以使用shutil.move:

    from shutil import move
    move(sourceplayers, destinationplayers)
    

    【讨论】:

    • 感谢您的回复。我只是添加了 /y 并且它工作得很好!
    【解决方案3】:

    根据TechNet docs,看起来xcopy 采用/y 标志“禁止提示确认您要覆盖现有目标文件。”

    我想你会这样使用它:

    os.system ("""xcopy "%s" "%s" /y""" % (sourceplayers, destinationplayers))
    

    【讨论】:

    • 感谢您提供该链接。它帮助解决了我的一些问题!
    【解决方案4】:

    您可以将 /y 开关作为 xcopy 命令的一部分传递,以始终覆盖文件,但如果您严格希望根据您的问题提供输入(全选),请尝试类似 https://github.com/pexpect/pexpect

    【讨论】:

    • 感谢您的回复!我添加了 /y 并修复了它!