2015-05-06 9 views
5

muszę obsługiwać sygnały w moim kodu i używam globalny stan podzielić między funkcjami:Co to jest Pythonowy sposób udostępniania stanu w jednym module?

exit = False 

def setup_handler(): 
    signal.signal(signal.SIGTERM, handler) 

def handler(num, frame): 
    global exit 
    exit = True 

def my_main(): 
    global exit 
    while not exit: 
     do_something() 

if __name__ == '__main__': 
    setup_handler() 
    my_main() 

Czy istnieje sposób, aby uniknąć zmienną globalną w tym przypadku? Jaki jest najlepszy sposób na dzielenie się stanem w tym przypadku?

+1

Czy naprawdę chcesz robić 'do_something' tak szybko, jak pozwala na to procesor? Jeśli masz na myśli określoną rozdzielczość czasową, powinieneś nazwać 'my_main' z' handler' co każde 'n' sekund. –

+0

@Asad to uproszczony kod dla jasności. Nie działa tak szybko, jak pozwala na to procesor. – Cory

Odpowiedz

6

Możesz użyć klasy do enkapsulacji modułu globalnie, ale to, czy warto to robić, zależy od tego, jak bardzo chcesz uniknąć globalnego.

class EventLoop(object): 
    def __init__(self): 
     self.exit = False 

    def run(self): 
     while not self.exit: 
      do_something() 

    def handler(self): 
     self.exit = True  

# It's up to you if you want an EventLoop instance 
# as an argument, or just a reference to the instance's 
# handler method. 
def setup_handler(event_loop): 
    signal.signal(signal.SIGTERM, event_loop.handler) 


if __name__ == '__main__': 
    loop = EventLoop() 
    setup_handler(loop) 
    loop.run() 
+0

Klasa jest drogą do zrobienia. Jeśli masz kilka takich stanów, możesz umieścić stan w "klasie konfiguracyjnej" i przekazać tę klasę config do '__init __()' metod kilku klas, aby umożliwić im dzielenie się stanem w oczywisty sposób. –

+0

Jest to konieczne w przypadku aplikacji wielowątkowych, w których powinny być wyłączone tylko określone wątki - w przeciwnym razie wszyscy zostaną wyłączeni, gdy zobaczą flagę. – alexis

+0

Warto zauważyć, że użycie klasy spowoduje (mały) wyciek pamięci, jeśli proces będzie kontynuowany po przetworzeniu sygnału. Moduł sygnału będzie zachowywał odniesienie do metody 'handler', która będzie zachowywać odniesienie do jej obiektu. Możesz chcieć, aby przewodnik wyrejestrował się z modułem sygnałowym. – Dunes

Powiązane problemy