Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using variables in signal handler - require global?

Tags:

python

I have a signal handler to handle ctrl-c interrupt. If in the signal handler I want to read a variable set in my main script, is there an alternative to using a "global" statement when setting the variable?

I don't mind doing this, but read this post (Do you use the "global" statement in Python?) in which someone commented that there should be no reason to ever use global.

What is the alternative in this case?

My code looks like this:

 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() 
like image 566
Joe Watkins Avatar asked Sep 11 '12 13:09

Joe Watkins


People also ask

How can parameters be used to avoid the use of global variables?

Parameter passing - allows the values of local variables within the main program to be passed to sub-programs without the need to use global variables. The value of these variables (or a copy of the value of these variables) is passed as a parameter to and from sub-programs as necessary.

Should you use global variables?

Using global variables causes very tight coupling of code. Using global variables causes namespace pollution. This may lead to unnecessarily reassigning a global value. Testing in programs using global variables can be a huge pain as it is difficult to decouple them when testing.

Can global variables be used anywhere?

You can access the global variables from anywhere in the program. However, you can only access the local variables from the function. Additionally, if you need to change a global variable from a function, you need to declare that the variable is global. You can do this using the "global" keyword.

How do you avoid global variables?

The simplest way to avoid globals all together is to simply pass your variables using function arguments. As you can see, the $productData array from the controller (via HTTP request) goes through different layer: The controller receives the HTTP request. The parameters are passed to the model.


2 Answers

You can use a closure as the signal handler that acquires its state from the main script:

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() 
like image 166
Henry Gomersall Avatar answered Oct 19 '22 21:10

Henry Gomersall


You can use partial to create a "closure".

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() 
like image 32
Ale Avatar answered Oct 19 '22 19:10

Ale