我正在尝试覆盖文件。我的答案基于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
。
以下是我要实现的目标:
cat_desc
custom
,则必须删除cat_desc
并替换为custom
。答案 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'))