python-如果程序崩溃,如何恢复FOR循环?
此程序非常依赖于网络,有时网络会崩溃 有一种方法可以恢复“for循环”,以防程序崩溃,下次我启动程序时,它将在程序崩溃的同一用户中启动 守则:python-如果程序崩溃,如何恢复FOR循环?,python,for-loop,Python,For Loop,此程序非常依赖于网络,有时网络会崩溃 有一种方法可以恢复“for循环”,以防程序崩溃,下次我启动程序时,它将在程序崩溃的同一用户中启动 守则: users = [ {'username': 'user1', 'email': 'mail1@mail.com'}, {'username': 'user2', 'email': 'mail2@mail.com'}, {'username': 'user3', 'email': 'mai
users = [
{'username': 'user1', 'email': 'mail1@mail.com'},
{'username': 'user2', 'email': 'mail2@mail.com'},
{'username': 'user3', 'email': 'mail3@mail.com'},
{'username': 'user4', 'email': 'mail4@mail.com'},
]
try:
text_file = open("current_username.txt", "w")
for item in users:
text_file.seek(0)
text_file.truncate()
text_file.write(item['username'])
# BEGIN, some relevant code that sometimes crashes and don't is code dependent
# ...
# END, some relevant code that sometimes crashes and don't is code dependent
text_file.close()
except:
text_file.close()
关于我下次启动程序时如何启动的线索,它将在导致代码崩溃的同一个“用户名”上启动吗?这取决于恢复的关键程度 对于一种简单、非关键的方法,使用上下文管理器和
with
语句将更好地处理异常,并使您的初始写入(用户名)
更可能写入文件,以便您可以使用它来恢复当前用户:
with open("current_username.txt", "w") as text_file:
for item in users:
text_file.seek(0)
...
带有的将在文件退出或出现异常时关闭文件并释放资源
对于恢复,您可以使用itertools.takewhile()
,例如(伪代码),为当前用户使用迭代器:
这确实取决于恢复的关键程度
对于一种简单、非关键的方法,使用上下文管理器和with
语句将更好地处理异常,并使您的初始写入(用户名)
更可能写入文件,以便您可以使用它来恢复当前用户:
with open("current_username.txt", "w") as text_file:
for item in users:
text_file.seek(0)
...
带有
的将在文件退出或出现异常时关闭文件并释放资源
对于恢复,您可以使用itertools.takewhile()
,例如(伪代码),为当前用户使用迭代器:
如果崩溃不依赖于代码,我建议使用索引进行不同的迭代,然后将该索引存储在硬盘中。
我不是这个解决方案的真正粉丝,但这可能是您想要的:
users = [
{1:{'username': 'user1', 'email': 'mail1@mail.com'}},
{2:{'username': 'user2', 'email': 'mail2@mail.com'}},
{3:{'username': 'user3', 'email': 'mail3@mail.com'}},
{4:{'username': 'user4', 'email': 'mail4@mail.com'}},
]
counter = 0
try:
saveFile = open('saveFile.txt','r')
counter = int(saveFile.read())
saveFile.close()
except IOError:
pass
try:
text_file = open("current_username.txt", "w")
for i in range(counter,len(users)):
item = users[i]
text_file.seek(0)
text_file.truncate()
text_file.write(item['username'])
# BEGIN, some relevant code that sometimes crashes and don't is code dependent
# ...
# END, some relevant code that sometimes crashes and don't is code dependent
counter = i
text_file.close()
except:
saveFile = open('savefile.txt','w+')
saveFile.write(counter)
saveFile.close()
text_file.close()
尽管如此,如果在处理数据时发生崩溃,这也不会节省您的时间,因为操作不是原子操作。当您完成对项的处理时,会保存进度,因此我认为您可能会有重复的数据。如果您的崩溃与代码无关,我建议使用索引进行不同的迭代,然后将此索引存储在硬盘中。
我不是这个解决方案的真正粉丝,但这可能是您想要的:
users = [
{1:{'username': 'user1', 'email': 'mail1@mail.com'}},
{2:{'username': 'user2', 'email': 'mail2@mail.com'}},
{3:{'username': 'user3', 'email': 'mail3@mail.com'}},
{4:{'username': 'user4', 'email': 'mail4@mail.com'}},
]
counter = 0
try:
saveFile = open('saveFile.txt','r')
counter = int(saveFile.read())
saveFile.close()
except IOError:
pass
try:
text_file = open("current_username.txt", "w")
for i in range(counter,len(users)):
item = users[i]
text_file.seek(0)
text_file.truncate()
text_file.write(item['username'])
# BEGIN, some relevant code that sometimes crashes and don't is code dependent
# ...
# END, some relevant code that sometimes crashes and don't is code dependent
counter = i
text_file.close()
except:
saveFile = open('savefile.txt','w+')
saveFile.write(counter)
saveFile.close()
text_file.close()
尽管如此,如果在处理数据时发生崩溃,这也不会节省您的时间,因为操作不是原子操作。当您完成对项的处理时,进度会被保存下来,因此我认为您可能会有重复的数据。最简单的方法可能是将for
循环中的内容包装到另一个循环中,并仅在成功时退出。此外,您可能希望将with与as
构造一起使用
with open("current_username.txt", "w") as text_file:
for item in users:
text_file.seek(0)
text_file.truncate()
text_file.write(item['username'])
while True:
try:
# BEGIN, some relevant code that sometimes crashes and don't is code dependent
# ...
# END, some relevant code that sometimes crashes and don't is code dependent
except: # Should probably specify a specific error type
# Possibly undo changes made above
pass
else:
break
# text_file is automatically closed when the `with` block is exited
最简单的方法可能是将for
循环中的内容包装到另一个循环中,并仅在成功时退出。此外,您可能希望将with与as
构造一起使用
with open("current_username.txt", "w") as text_file:
for item in users:
text_file.seek(0)
text_file.truncate()
text_file.write(item['username'])
while True:
try:
# BEGIN, some relevant code that sometimes crashes and don't is code dependent
# ...
# END, some relevant code that sometimes crashes and don't is code dependent
except: # Should probably specify a specific error type
# Possibly undo changes made above
pass
else:
break
# text_file is automatically closed when the `with` block is exited
我建议你试试。这是序列化对象的最简单方法,可用于保存状态
您可以执行以下操作来恢复循环:
import pickle
'''
Your other code here
'''
global REGISTRY
start = pickle.loads(REGISTRY) if REGISTRY else 0
for i in xrange(start, len(users)):
text_file.seek(0)
text_file.truncate()
text_file.write(item['username'])
REGISTRY = pickle.dumps(i)
我建议你试试。这是序列化对象的最简单方法,可用于保存状态
您可以执行以下操作来恢复循环:
import pickle
'''
Your other code here
'''
global REGISTRY
start = pickle.loads(REGISTRY) if REGISTRY else 0
for i in xrange(start, len(users)):
text_file.seek(0)
text_file.truncate()
text_file.write(item['username'])
REGISTRY = pickle.dumps(i)
使用相同的代码并进行了一些调整
users = [
{'username': 'user1', 'email': 'mail1@mail.com'},
{'username': 'user2', 'email': 'mail2@mail.com'},
{'username': 'user3', 'email': 'mail3@mail.com'},
{'username': 'user4', 'email': 'mail4@mail.com'},
]
try:
#Open file to Read / Write, note the 'r+'
text_file = open("current_username.txt", "r+")
text_file.seek(0)
#Read the last user written in the file
current_user = text_file.readline()
last_index = 0
if current_user is not '':
for last in range(len(users)):
if users[last]['username'] == current_user:
last_index = last
break
for index in range(last_index, len(users)):
text_file.seek(0)
text_file.truncate()
text_file.write(users[index]['username'])
print(users[index])
# BEGIN, some relevant code that sometimes crashes and don't is code dependent
# ...
# END, some relevant code that sometimes crashes and don't is code dependent
text_file.seek(0)
text_file.truncate()
text_file.write('')
text_file.close()
except Exception as e:
print(e)
text_file.close()
如果循环结束异常,则当前用户名.txt拥有最后一个用户,而第一个循环寻找最后一个索引并从那里开始,另一方面,如果当前用户名.txt没有任何数据,则下一个程序从开始执行。使用相同的代码并进行一些调整
users = [
{'username': 'user1', 'email': 'mail1@mail.com'},
{'username': 'user2', 'email': 'mail2@mail.com'},
{'username': 'user3', 'email': 'mail3@mail.com'},
{'username': 'user4', 'email': 'mail4@mail.com'},
]
try:
#Open file to Read / Write, note the 'r+'
text_file = open("current_username.txt", "r+")
text_file.seek(0)
#Read the last user written in the file
current_user = text_file.readline()
last_index = 0
if current_user is not '':
for last in range(len(users)):
if users[last]['username'] == current_user:
last_index = last
break
for index in range(last_index, len(users)):
text_file.seek(0)
text_file.truncate()
text_file.write(users[index]['username'])
print(users[index])
# BEGIN, some relevant code that sometimes crashes and don't is code dependent
# ...
# END, some relevant code that sometimes crashes and don't is code dependent
text_file.seek(0)
text_file.truncate()
text_file.write('')
text_file.close()
except Exception as e:
print(e)
text_file.close()
如果循环异常结束,则current_username.txt
拥有最后一个用户,而第一个循环寻找最后一个索引并从那里开始,另一方面,如果current_username.txt
没有任何数据,下一个程序从一开始就开始执行。显示如何以确保不会出现部分内容(或在意外崩溃时不会为空&c)的方式写入该文件是完成此答案的一个重要元素。相关:演示如何编写该文件,以确保不会出现部分内容(或在意外崩溃时不会为空&c)是完成此答案的一个重要元素。相关:当您打开('savefile.txt','w+')
,这将截断原始内容。此时的崩溃将使计数器完全清空。因此,这不是一种安全的原子文件更新方法。我打算擦除计数器的进度,因为每次保存新计数器时,我都需要覆盖它。但问题是,当文件暂时为空时,您会有一个瞬间,因此如果在错误的时间拔出电源(或您收到SIGKILL),程序的下一次调用不会在该调用停止的地方重新启动。还有其他更好的方法来替换没有此问题的文件内容。请参阅我在AChampion对答案的评论中发布的链接。打开('savefile.txt','w+')
时,会截断原始内容。此时的崩溃将使计数器完全清空。因此,这不是一种安全的原子文件更新方法。我打算擦除计数器的进度,因为每次保存新计数器时,我都需要覆盖它。但问题是,当文件暂时为空时,您会有一个瞬间,因此如果在错误的时间拔出电源(或您收到SIGKILL),程序的下一次调用不会在该调用停止的地方重新启动。还有其他更好的方法来替换没有此问题的文件内容。请参阅我在AChampion对答案的评论中发布的链接。如果您在truncate()
和write()
之间受到电源猛拉或SIGKILL,我们将回到起点。您需要调用flush()
,以确保写入操作能够及时执行。没错,我更关注的是如何优雅地处理(软战争)