如何覆盖Python中的文件?

问题描述:

我试图覆盖文件。我在此基础上Read and overwrite a file in Python如何覆盖Python中的文件?

我的答案来完成我的代码:

<select class="select compact expandable-list check-list" 
    ONCHANGE="location = this.options[this.selectedIndex].value;"> 
    <option value="{% url envelopes:auto_sort %}?sort_by=custom"> 
     Custom order 
    </option> 
    <optgroup label="Category"> 
     <option value="{% url envelopes:auto_sort %}?sort_by=cat_asc"> 
      Ascending order 
     </option> 
     <option value="{% url envelopes:auto_sort %}?sort_by=cat_desc"> 
      Descending order 
     </option> 
    </optgroup> 
</select> 

def auto_sort(request): 
    sort_by = request.GET.get('sort_by', None) 
    if sort_by: 
     temp_path = "{0}/file.txt".format(settings.SITE_ROOT) 

     f=open(temp_path,'r+') 
     text = f.read() 
     text = re.sub('cat_asc', 'cat_desc', text) 
     f.seek(0) 
     f.write(text) 
     f.truncate() 
     f.close(); 

     handle=open(temp_path,'w+') 
     handle.write(sort_by) 
     handle.close(); 

    return HttpResponseRedirect(reverse('envelopes:editor')) 

我目前的代码输出:

该文件包含cat_desc当我尝试为custom重写一遍。它改写为customc。注意c最后,它只能是custom

这里是我想要实现:

  1. 我写的文件,例如,cat_desc
  2. 如果我想再次写,例如custom,该cat_desc必须拆除并换成custom
+3

哪条线发生的错误? – Serdalis 2013-03-19 04:28:52

+0

http://docs.python.org/2/library/re.html#re.sub re.sub接受三个字符串参数'pattern'/'replacement','string'。第四个参数(你的“文本”参数)必须是一个指定计数的数字 – RedBaron 2013-03-19 04:48:06

+0

're.sub' _supposed_要做什么?参数在问题和回溯中的顺序不同! – 2013-03-19 04:48:11

根据修改后的问题,也许这样的事情会更简单

def auto_sort(request): 
    sort_by = request.GET.get('sort_by', None) 
    if sort_by: 
     temp_path = "{0}/file.txt".format(settings.SITE_ROOT) 
     #Set new_text to whatever you want based on your logic 
     new_text = 'custom' 
     f=open(temp_path,'w') 
     f.write(new_text) 
     f.close(); 

     handle=open(temp_path,'w+') 
     handle.write(sort_by) 
     handle.close(); 

    return HttpResponseRedirect(reverse('envelopes:editor')) 
+0

我再次收到错误TypeError:一个整数是必需的。这是之前的错误。 – catherine 2013-03-19 05:17:33

+0

删除re.sub部分。你不需要它 – RedBaron 2013-03-19 05:18:07

+0

它现在正在工作,我会测试这个 – catherine 2013-03-19 05:22:05

你可以复制和粘贴完整的错误回到

尝试:

def auto_sort(request): 
    sort_by = request.GET.get('sort_by', None) 
    if sort_by: 
     temp_path = "{0}/file.txt".format(settings.SITE_ROOT) 
     f=open(temp_path,'r') 
     text = f.read() 
     text = re.sub('custom', 'cat_asc', 'cat_desc', text) 
     f.close(); 
     handle=open(temp_path,'w') 
     handle.write(sort_by) 
     handle.close(); 
    return HttpResponseRedirect(reverse('envelopes:editor')) 
+0

再次出现同样的错误 – catherine 2013-03-19 04:40:29

新anwser ...

你传递textre.sub的第四个参数。这应该是一个int

Help on function sub in module re: 

sub(pattern, repl, string, count=0, flags=0) 
    Return the string obtained by replacing the leftmost 
    non-overlapping occurrences of the pattern in string by the 
    replacement repl. repl can be either a string or a callable; 
    if a string, backslash escapes in it are processed. If it is 
    a callable, it's passed the match object and must return 
    a replacement string to be used. 

老答案...

也许你正在做

from os import open 

这是一个不同的(下级)开放,你想只需使用内置的开放(你不需要输入任何东西使用它)

这里是一个EXA做错了,并得到你的错误信息

>>> from os import open 
>>> open("some_path", "r+") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: an integer is required 

也要覆盖文件,你需要打开“w +”。 “R”代表读

+0

我没有使用'从os导入打开' – catherine 2013-03-19 04:39:20

+0

@catherine,好的。问题与覆盖文件无关,它是使用're.sub' – 2013-03-19 04:46:47

您的问题无关,与写入文件。

回溯告诉你,此行是罪魁祸首:

File "/home/cath/src/envelopebudget/envelopebudget/settings/../apps/envelopes/views.py" in auto_sort 
    357.   text = re.sub('cat_desc', 'cat_asc', 'custom', text) 

如果你看一下re.sub方法,你调用一个错误:

re.sub(pattern, repl, string, count=0, flags=0) 

你传递'cat_desc'pattern,'cat_asc'作为repl,'custom'作为string和作为count作为text。这没有任何意义。 re.sub预计count是一个整数,并且您给它一个字符串。

+0

的扫描仪确定我已经擦除了该定制,现在它可以工作。但我试图实现的是完全重写文件。 – catherine 2013-03-19 04:47:50

+0

@catherine:好的,但如果这不起作用,你会遇到一个完全不同的问题,你需要告诉我们详细情况,最好是在一个新问题中。 – abarnert 2013-03-19 05:03:52

+0

它允许创建新的问题吗?我的问题是覆盖作为标题的文件。 – catherine 2013-03-19 05:09:53

对于新的问题:

试图覆盖就地文件基本上是不可能的,除非你有确切的相同长度的新字节字符串替换字节串。如果您将'cat_desc'替换为'cat_asc',那么您将以'cat_ascc'结束。

你在做什么 - 在'r+'模式下打开它,读取整个文件,处理它,将seek写入0,然后写入整个文件 - 确实有效。但这不是做事的最佳方式。

无论如何,你的问题是,在你做这件事之后,你需要在'w+'模式(截断文件)中打开完全相同的路径,然后写一些不同的东西。所以,无论你写什么现在都消失了。

解决方案是...不这样做。我不确定你想要做什么,但可能不是这样。

同时,重写文件的最佳方式是“原子写入温度和重命名”习语。这保证你永远不会损坏文件,你可以得到新文件或者仍旧保留旧文件。这也意味着你不必将整个文件保存在内存中;你可以一点一滴地去。这很简单...如果你不关心Windows。它的工作原理是这样的:

with tempfile.NamedTemporaryFile(delete=False) as outfile: 
    with open(inpath) as infile: 
     # copy from infile to outfile, changing things as you go 
    os.rename(outfile.name, inpath) 

不幸的是,在Windows上开展这项工作非常痛苦。当它仍然处于打开状态时,您不能移动outfile,并且您不能在with声明之外访问它,并且最重要的是,您不能仅使用outfile覆盖infile;你必须做一个复杂的洗牌。除非您愿意要求Vista/2008并直接调用Win32 API,否则它永远不会是完全原子的。

+0

谢谢我现在明白为什么我会得到该输出 – catherine 2013-03-19 05:26:42