Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在编辑器中打开文件,而文件';它在脚本中打开_Python_Linux_Windows_File Io_Io - Fatal编程技术网

Python 在编辑器中打开文件,而文件';它在脚本中打开

Python 在编辑器中打开文件,而文件';它在脚本中打开,python,linux,windows,file-io,io,Python,Linux,Windows,File Io,Io,我有以下代码: import os import sys import tempfile import subprocess with tempfile.NamedTemporaryFile('w+') as f: if sys.platform == 'linux': subprocess.call('vim', f.name) elif sys.platform == 'nt': os.system(f.name) 它在Linux上使用vi

我有以下代码:

import os
import sys
import tempfile
import subprocess

with tempfile.NamedTemporaryFile('w+') as f:
    if sys.platform == 'linux':
        subprocess.call('vim', f.name)
    elif sys.platform == 'nt':
        os.system(f.name)
它在Linux上使用
vim
或Windows上的默认编辑器打开
foobar.txt
。在Linux上,它可以正常工作:创建一个临时文件并
vim
打开它。然而,在Windows上,系统显示:

进程无法访问该文件,因为其他进程正在使用该文件

我猜这是因为脚本当前正在使用该文件


为什么它可以在Linux上工作,我如何让它在Windows上工作?

我以前遇到过这个问题。我的问题是,我必须写入一个文件,然后在命令中使用该文件的名称作为参数

这在Linux中起作用的原因是,正如评论中所说,Linux允许多个进程写入同一个文件,但Windows不允许

有两种方法可以解决这个问题

一种是创建一个目录并在该目录中创建一个文件

# Python 2 and 3
import os
import tempfile

temp_dir = tempfile.mkdtemp()
try:
    temp_file = os.path.join(temp_dir, 'file.txt')
    with open(temp_file, 'w') as f:
        pass  # Create the file, or optionally write to it.
    try:
        do_stuff(temp_file)  # In this case, open the file in an editor.
    finally:
        os.remove(file_name)
finally:
    os.rmdir(temp_dir)
另一种方法是使用
delete=False
创建临时文件,这样当您关闭它时,它不会被删除,然后在以后手动删除

# Python 2 and 3
import os
import tempfile

fp = tempfile.NamedTemporaryFile(suffix='.txt', delete=False)
try:
    fp.close()
    do_stuff(fp.name)
finally:
    os.remove(fp.name)
下面是一个可以生成文件的小上下文管理器:

import os
import tempfile

_text_type = type(u'')

class ClosedTemporaryFile(object):
    __slots__ = ('name',)
    def __init__(self, data=b'', suffix='', prefix='tmp', dir=None):
        fp = tempfile.mkstemp(suffix, prefix, dir, isinstance(data, _text_type))
        self.name = fp.name
        if data:
            try:
                fp.write(data)
            except:
                fp.close()
                self.delete()
                raise
        fp.close()

    def exists(self):
        return os.path.isfile(self.name)

    def delete(self):
        try:
            os.remove(self.name)
        except OSError:
            pass

    def open(self, *args, **kwargs):
        return open(self.name, *args, **kwargs)

    def __enter__(self):
        return self.name

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.delete()

    def __del__(self):
        self.delete()
用法:

with ClosedTemporaryFile(suffix='.txt') as temp_file:
    do_stuff(temp_file)

这是基本的Windows I/O。所有文件都以特定的访问权限(读/写数据、删除、设置属性等)和访问共享模式打开
NamedTemporary
根据关闭时删除标志的要求,打开具有删除访问权限的文件,并共享所有访问权限(读取、写入和删除)。随后再次打开文件需要共享删除访问权限,这是大多数程序不允许的。仅供参考,您可以通过在关闭第一个句柄之前打开文件的第二个句柄来撤消关闭时删除标志的效果。关闭第一个句柄时,它会对文件设置删除处置,但在关闭所有句柄之前不会删除该句柄。使用第二个句柄通过
SetFileInformationByHandle
撤消删除处理。现在你可以关闭第二个手柄,文件就不会被删除了。哈哈,@KevinGuan很早就认识Eriksun了,他在评论中解决的问题比答案多,这也是我喜欢他作为一个人的原因之一。:)@KevinGuan:如果你关闭一个
tempfile.NamedTemporaryFile
(或者一个普通的
tempfile.TemporaryFile`),它将被销毁。见[文件](https://docs.python.org/3/library/tempfile.html)详情请参阅。也许您可以使用
tempfile.mkstemp`file?@KevinGuan:Unix允许多个进程写入同一个文件,但您必须小心,如中所述。
with ClosedTemporaryFile(suffix='.txt') as temp_file:
    do_stuff(temp_file)