如何用Python覆盖文件?

cat*_*ine 6 python file

我正在尝试覆盖文件.我的回答基于这个Read并用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'))
Run Code Online (Sandbox Code Playgroud)

我当前代码的输出:

cat_desc当我再次尝试重写时,该文件包含custom.它重写为customc.注意c最后,它必须是custom唯一的.

这是我想要实现的目标:

  1. 我写文件,例如, cat_desc
  2. 例如custom,如果我想再写一次,cat_desc必须将其删除并替换为custom.

Joh*_*ooy 5

新的anwser ...

text作为第四个参数传递re.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.
Run Code Online (Sandbox Code Playgroud)

老答案......

也许你在做

from os import open
Run Code Online (Sandbox Code Playgroud)

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

这是一个错误的例子,并收到你的错误信息

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

要覆盖文件,还需要打开"w +"."r"代表阅读


aba*_*ert 5

对于您的新问题:

尝试就地覆盖文件基本上是不可能的,除非你用完全相同长度的新字节字符串替换字节字符串.如果您替换'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)
Run Code Online (Sandbox Code Playgroud)

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


Red*_*ron 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'))
Run Code Online (Sandbox Code Playgroud)