我在这里有以下代码。我想要做的是我想脚本扫描我的IP地址,然后做一些工作。
我的问题是,即使我没有关闭带有主机名IP的手机WIFI,MP3也会每30秒重复一次。
我希望MP3只在脚本找到IP后播放一次,但扫描将继续扫描。
这可能吗?任何帮助将非常感谢
#!/usr/bin/env python
import os, sys
import sched, time
s = sched.scheduler(time.time, time.sleep)
def do_something(sc):
import os
hostname = "192.168.254.102" #example
response = os.system("ping -c 1 " + hostname)
if response == 0:
print(hostname, 'is up!')
os.system("sudo python ../aquarium/nightlight_on.py 1")
os.system("omxplayer -o local ../music/jarvis_on.mp3 1")
else:
print(hostname, 'is down!')
os.system("sudo python ../aquarium/nightlight_off.py 1")
sc.enter(160, 1, do_something, (sc,))
s.enter(30, 1, do_something, (s,))
s.run()
答案 0 :(得分:1)
如果我了解您正在尝试正确执行的操作,则您希望在IP加密的可用性时运行某些行为,并且您正在扫描更改。也就是说,您希望在可用时(在关闭之后)执行一个操作,并在其关闭时(在可用之后)执行不同的操作。如果它继续做以前做过的事情,你就不想做任何事情。
这要求您让函数访问某种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()