[英]How to overwrite a file in Python?
I'm trying to overwrite a file. 我正在尝试覆盖文件。 I based my answer on this Read and overwrite a file in Python
我基于此答案在Python中读取和覆盖文件
To complete my codes: 要完成我的代码:
<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'))
The output of my current codes: 我当前代码的输出:
The file contains cat_desc
when I try rewrite again as custom
. 当我尝试再次按
custom
重写时,文件包含cat_desc
。 It rewrites as customc
. 它重写为
customc
。 Notice the c
at the end, it must be custom
only. 请注意最后的
c
,它只能是custom
。
Here is what I'm trying to achieve: 这是我要实现的目标:
cat_desc
cat_desc
custom
, the cat_desc
must be removed and replaced with custom
. custom
,必须删除cat_desc
并用custom
代替。 New anwser ... 新的安瑟尔...
You're passing text
as the 4th parameter of re.sub
. 您正在传递
text
作为re.sub
的第四个参数。 This is supposed to be an int
这应该是一个
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.
old answer ... 旧答案...
Perhaps you are doing 也许你在做
from os import open
That is a different (lower level) open, you want to just use the builtin open (you don't need to import anything to use it) 那是一个不同的(较低级别的)开放,您只想使用内置的开放(您不需要导入任何内容即可使用它)
Here is an example of doing it wrong and getting your error message 这是做错事并得到错误消息的示例
>>> from os import open
>>> open("some_path", "r+")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: an integer is required
Also to overwrite the file, you need to open with "w+". 同样,要覆盖文件,您需要使用“ w +”打开。 "r" stands for read
“ r”代表阅读
For your new question: 对于您的新问题:
Trying to overwrite a file in-place is basically impossible, unless you're replacing byte strings with new byte strings of the exact same length. 基本上就不可能尝试就地覆盖文件,除非您用完全相同长度的新字节字符串替换字节字符串。 If you replace
'cat_desc'
with 'cat_asc'
, you're going to end up with 'cat_ascc'
. 如果将
'cat_desc'
替换为'cat_asc'
,您将最终得到'cat_ascc'
。
What you're doing—opening it in 'r+'
mode, reading the whole thing, processing it, seek
ing to 0, and writing the whole thing—does work. 您正在做的事情-在
'r+'
模式下打开它,读取整个内容,对其进行处理, seek
到0,然后编写整个内容-可以正常工作。 But it's not the best way to do things. 但这不是做事情的最佳方法。
And at any rate, your problem is that immediately after you do this, you open the exact same path in 'w+'
mode (which truncates the file) and write something different. 无论如何,您的问题是,执行此操作后,立即在
'w+'
模式(截断文件)中打开了完全相同的路径,并编写了不同的内容。 So, whatever you wrote is now gone. 因此,无论您写什么,现在都消失了。
The solution to that is… don't do that. 解决方案是……不要那样做。 I'm not sure what you were trying to do, but that probably isn't it.
我不确定您要做什么,但这可能不是。
Meanwhile, the best way to rewrite a file is the "atomic write temp and rename" idiom. 同时,重写文件的最佳方法是“原子写入临时和重命名”习惯用法。 This guarantees that you never corrupt the file, you either get the new file or still have the old one.
这样可以确保您永远不会损坏该文件,无论是获取新文件还是保留旧文件。 It also means you don't have to keep the whole file around in memory;
这也意味着您不必将整个文件保留在内存中; you can go bit by bit.
你可以一点一点走。 And it's very simple… if you don't care about Windows.
而且非常简单……如果您不关心Windows。 It works like this:
它是这样的:
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)
Unfortunately, making this work on Windows is very painful. 不幸的是,在Windows上进行这项工作非常痛苦。 You can't move
outfile
while it's still open, and you can't access it outside the with
statement, and on top of that you can't just overwrite infile
with outfile
; 您不能在
outfile
仍处于打开状态时移动它,也不能在with
语句之外访问它,最重要的是,您不能仅使用outfile
覆盖infile
; you have to do a complicated shuffle. 您必须进行复杂的洗牌。 And it's never going to be completely atomic, unless you're willing to require Vista/2008 and to call Win32 APIs directly.
除非您愿意要求Vista / 2008并直接调用Win32 API,否则它永远不会是原子的。
Based on your revised question, maybe something like this would be simpler 根据您修改的问题,也许像这样的事情会更简单
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'))
Your problem has nothing to do with writing a file. 您的问题与写入文件无关。
The traceback tells you that this line is the culprit: 追溯告诉您此行是罪魁祸首:
File "/home/cath/src/envelopebudget/envelopebudget/settings/../apps/envelopes/views.py" in auto_sort
357. text = re.sub('cat_desc', 'cat_asc', 'custom', text)
If you look at the re.sub
method, you're calling it wrong: 如果您查看
re.sub
方法,则称它为错误的:
re.sub(pattern, repl, string, count=0, flags=0)
You're passing 'cat_desc'
as the pattern
, 'cat_asc'
as the repl
, 'custom'
as the string
, and text
as the count
. 你传递
'cat_desc'
为pattern
, 'cat_asc'
作为repl
, 'custom'
的string
,而text
的count
。 That doesn't make any sense. 那没有任何意义。
re.sub
expects the count
to be an integer, and you've given it a string. re.sub
期望该count
为整数,并且已为其指定了字符串。
Can you copy and paste the full error back 您能复制并粘贴完整错误吗
Try: 尝试:
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'))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.