假设您正在处理一些您无法信任的恶劣代码,是否有办法安全地运行它而不会失去对脚本的控制?
一个例子可能是一个只在某些时候起作用的功能,并且可能会随机/壮观地失败,你怎么能重试直到它工作?我尝试使用线程模块进行一些黑客攻击,但很难整齐地杀死一个挂起的线程。
#!/usr/bin/env python
import os
import sys
import random
def unreliable_code():
def ok():
return "it worked!!"
def fail():
return "it didn't work"
def crash():
1/0
def hang():
while True:
pass
def bye():
os._exit(0)
return random.choice([ok, fail, crash, hang, bye])()
result = None
while result != "it worked!!":
# ???
答案 0 :(得分:5)
为了安全抵御异常,请使用try / except(但我想你知道)。
为了安全地防止挂起代码(无限循环),我知道的唯一方法是在另一个进程中运行代码。这个子进程可以从父进程中终止,以防它不能很快终止。
为了安全抵御令人讨厌的代码(不应该做的事情),请查看http://pypi.python.org/pypi/RestrictedPython。
答案 1 :(得分:4)
您可以尝试在sandbox中运行它。
答案 2 :(得分:4)
在您的实际案例中,您可以切换到多处理吗?请注意,您提出的问题似乎可以通过multiprocessing
+ threading.Timer
+ try/except
完成。
看看这个:
class SafeProcess(Process):
def __init__(self, queue, *args, **kwargs):
self.queue = queue
super().__init__(*args, **kwargs)
def run(self):
print('Running')
try:
result = self._target(*self._args, **self._kwargs)
self.queue.put_nowait(result)
except:
print('Exception')
result = None
while result != 'it worked!!':
q = Queue()
p = SafeProcess(q, target=unreliable_code)
p.start()
t = Timer(1, p.terminate) # in case it should hang
t.start()
p.join()
t.cancel()
try:
result = q.get_nowait()
except queues.Empty:
print('Empty')
print(result)
在一个(幸运的)案例中,我给了我:
Running
Empty
None
Running
it worked!!
在您的代码示例中,您有五分之四的机会获得错误,因此您也可能会产生一个池或其他东西,以提高您获得正确结果的机会。