我有一个处理ctrl-c中断的信号处理程序。如果在信号处理程序中我想读取我的主脚本中的变量集,那么在设置变量时是否可以使用“global”语句?
我不介意这样做,但请阅读这篇文章(Do you use the "global" statement in Python?),其中有人评论说没有理由使用全局。
在这种情况下有什么替代方案?
我的代码如下所示:
def signal_handler(signal, frame):
print "in sig handler - g_var=%s" % g_var
def main():
global g_var
g_var = "test"
time.sleep(120)
if __name__ == '__main__':
signal.signal(signal.SIGINT, signal_handler)
main()
答案 0 :(得分:25)
您可以使用闭包作为从主脚本获取其状态的信号处理程序:
import signal
import sys
import time
def main_function():
data_for_signal_handler = 10
def signal_handler(*args):
print data_for_signal_handler
sys.exit()
signal.signal(signal.SIGINT, signal_handler) # Or whatever signal
while True:
data_for_signal_handler += 1
time.sleep(0.5)
if __name__ == '__main__':
main_function()
答案 1 :(得分:11)
您可以使用partial
创建"关闭"。
import signal
from functools import partial
def signal_handler(g_var, signal, frame):
print "in sig handler - g_var=%s" % g_var
def main():
g_var = "test"
signal.signal(signal.SIGINT, partial(signal_handler, g_var))
time.sleep(120)
if __name__ == '__main__':
main()
答案 2 :(得分:5)
在面向对象的范例(OOP)中,为此目的使用lambdas非常方便。使用lambdas可以传递一些额外的上下文(比如 self 引用)和/或去除未使用的参数( signal , frame )。
import time
import signal
class Application:
def __init__( self ):
signal.signal( signal.SIGINT, lambda signal, frame: self._signal_handler() )
self.terminated = False
def _signal_handler( self ):
self.terminated = True
def MainLoop( self ):
while not self.terminated:
print( "I'm just doing my job like everyone else" )
time.sleep( 3 )
app = Application()
app.MainLoop()
print( "The app is terminated, exiting ..." )
答案 3 :(得分:1)
您可以从内联定义的函数中访问外部作用域变量,如下所示:
my_values = {'foo':'bar'}
def handler(signum, frame):
for key,val in my_values.items():
print key,val
my_values['bat']='baz'
#remember to use mutable types, like dicts or lists
signal.signal(signal.SIGINT, handler)
答案 4 :(得分:0)
如果您只是阅读变量,则不需要将变量设为“全局”
def foo():
print a
a = 3
foo() #3
global是必要的,允许您更改变量并将该更改传播到模块名称空间。
如果你想在不使用global的情况下将一些状态传递给你的回调,那么我们使用实例方法作为回调的典型方法就是:
class foo(object):
def __init__(self,arg):
self.arg = arg
def callback_print_arg(self):
print self.arg
def call_callback(callback):
callback()
a = foo(42)
call_callback(a.callback_print_arg) #42