如果我明白你正確地做什麼,你想運行某些行爲時,IP的可用性adderss您掃描更改。也就是說,當一個動作變爲可用時(在關閉後)以及在其下降時(在可用後)執行一個不同的動作時,您想要執行一個動作。如果它繼續做同樣的事情,你不想做任何事情。
這要求你讓你的函數訪問某種state
變量。局部變量將不起作用,因爲您從調度程序重複調用該函數(而不是編寫自己的循環)。我認爲有三個合理的選擇。
最簡單的(從當前代碼需要改變多少的角度來看)是使用全局變量。像這樣將工作:
import os, sys
import sched, time
state = None
def do_something(sc):
global state # global statement is required since we write to the global state
hostname = "192.168.254.102" #example
response = os.system("ping -c 1 " + hostname)
if response == 0 and state != "up":
state = "up"
print(hostname, 'is up!')
os.system("sudo python ../aquarium/nightlight_on.py 1")
os.system("omxplayer -o local ../music/jarvis_on.mp3 1")
elif state != "down":
state = "down"
print(hostname, 'is down!')
os.system("sudo python ../aquarium/nightlight_off.py 1")
sc.enter(160, 1, do_something, (sc,))
s = sched.scheduler(time.time, time.sleep)
s.enter(30, 1, do_something, (s,))
s.run()
全局變量通常被認爲是不好的編程習慣,因爲它們弄亂全局命名空間,尤其是在這樣的情況下,當你將不會被訪問,從任何其他代碼state
變量。對於這樣的小腳本來說並不是什麼大事,但在更復雜的代碼中這樣做是一個壞主意。
下一個選擇使用閉包來保存狀態變量。閉包是內部函數可以訪問的外部函數的名稱空間。要寫入閉包中的變量,您需要使用nonlocal
語句,就像前一版本代碼中的global
語句一樣(這隻適用於您看起來像使用的Python 3):
import os, sys
import sched, time
def do_something_factory():
state = None # state is a local variable in the factory function's namespace
def do_something(sc):
nonlocal state # nonlocal statement lets us write to the outer scope
hostname = "192.168.254.102" #example
response = os.system("ping -c 1 " + hostname)
if response == 0 and state != "up":
state = "up"
print(hostname, 'is up!')
os.system("sudo python ../aquarium/nightlight_on.py 1")
os.system("omxplayer -o local ../music/jarvis_on.mp3 1")
elif state != "down":
state = "down"
print(hostname, 'is down!')
os.system("sudo python ../aquarium/nightlight_off.py 1")
sc.enter(160, 1, do_something, (sc,))
return do_something # return inner function to caller
s = sched.scheduler(time.time, time.sleep)
s.enter(30, 1, do_something_factory(), (s,)) # call factory function here!
s.run()
最後的辦法是用class
來包含函數(作爲方法)。狀態將被存儲在一個實例變量中,通過self
訪問。主腳本代碼將創建該對象,然後將綁定的方法傳遞給調度器。如果你願意,你也許可以將部分或全部代碼移入類中,但現在我會將設計保持不變。
import os, sys
import sched, time
class Doer(object):
def __init__(self):
self.state = None
def do_something(self, sc):
hostname = "192.168.254.102" #example
response = os.system("ping -c 1 " + hostname)
if response == 0 and self.state != "up":
self.state = "up"
print(hostname, 'is up!')
os.system("sudo python ../aquarium/nightlight_on.py 1")
os.system("omxplayer -o local ../music/jarvis_on.mp3 1")
elif self.state != "down":
self.state = "down"
print(hostname, 'is down!')
os.system("sudo python ../aquarium/nightlight_off.py 1")
sc.enter(160, 1, self.do_something, (sc,))
s = sched.scheduler(time.time, time.sleep)
d = Doer()
s.enter(30, 1, d.do_something, (s,))
s.run()
您好@Blckknght非常感謝您的回覆。不幸的是,我正在運行python 2.7.3版本。我已經嘗試過上面最簡單的答案,但沒有錯誤,但仍然是MP3循環...如果我將升級我的Python版本,會傷害我的系統嗎? 由於我的python版本,這兩個或你的答案有錯誤。錯誤是「NameError:全局名稱'do_something'未定義 」 –
是的,Python 2不允許在中間解決方案中使用'nonlocal'語句。最後一個版本有一個拼寫錯誤,如果你在'sc.enter'調用中添加'self',它應該可以工作(我已經編輯了上面的代碼)。我不知道爲什麼你仍然在第一個版本上得到循環。它應該只在開始時調用一次'omxplayer'命令,然後每次系統在關閉後恢復一次。它打印出什麼? – Blckknght