如何用Python覆盖文件?

时间:2013-03-19 04:19:28

标签: python file

我正在尝试覆盖文件。我的答案基于Read and overwrite a file in 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

5 个答案:

答案 0 :(得分:5)

New anwser ...

您将text作为re.sub的第4个参数传递。这应该是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

这是一个不同的(较低级别)打开,你想只使用内置打开(你不需要导入任何东西来使用它)

以下是错误操作并收到错误消息的示例

>>> 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”代表阅读

答案 1 :(得分:5)

对于您的新问题:

尝试就地覆盖文件基本上是不可能的,除非您用完全相同长度的新字节字符串替换字节字符串。如果您将'cat_desc'替换为'cat_asc',则最终会以'cat_ascc'结束。

你正在做什么 - 在'r+'模式下打开它,阅读整个事物,处理它,seek到0,然后编写整个事情 - 确实有效。但这不是最好的做事方式。

无论如何,您的问题是,在您执行此操作后,立即在'w+'模式下打开完全相同的路径(截断文件)并编写不同的内容。所以,无论你写什么,现在都没了。

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

同时,重写文件的最佳方法是&#34;原子写入临时和重命名&#34;成语。这可以保证您永远不会损坏文件,您可以获取新文件,也可以使用旧文件。这也意味着你不必将整个文件保存在内存中;你可以一点一点地去。它非常简单......如果你不关心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,并且无法在infile声明之外访问outfile,除此之外您无法移动{{1}}只需使用{{1}}覆盖{{1}};你必须做一个复杂的洗牌。它永远不会完全是原子的,除非你愿意要求Vista / 2008并直接调用Win32 API。

答案 2 :(得分:4)

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

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'))

答案 3 :(得分:2)

您的问题与编写文件无关。

追溯告诉你这一行是罪魁祸首:

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,{{1作为text。这没有任何意义。 count期望re.sub是一个整数,并且你给它一个字符串。

答案 4 :(得分:-1)

可以复制并粘贴完整的错误吗

尝试:

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'))