我正在尝试制作一个有效的闹钟程序。 它看起来比它看起来要复杂得多,但有理由,我不会进入这里。 我遇到的问题是,我在嵌套函数中创建一个Alarm对象,但无论我做什么,我都无法在该函数之外访问该对象...我附上了删节代码下面。 在setAlarm之外的任何“check”或“set”等调用都无法找到“alarm”变量。 请让我知道我做错了什么 - 我试着将变量声明为全局变量,正如你所看到的那样,但它仍然无法解决...
谢谢!
class Alarm(threading.Thread): def __init__(self, datetime, grace, close): super(Alarm, self).__init__() self.datetime = datetime self.grace = grace self.close = close self.keep_running = True def run(self): try: while self.keep_running: now = datetime.datetime.now() if now > self.datetime + datetime.timedelta(minutes=self.grace): print "Oh no! It's %02d:%02d, which is %d minutes past your alarm time of %02d:%02d!" % (now.hour,now.minute,self.grace,self.datetime.hour,self.datetime.minute) print "ALARM NOW!\a\a\a\a\a\a\a\a\a\a" break time.sleep(10) except: return def just_die(self): self.keep_running = False def setAlarm(): print "What time would you like to set the alarm for? (in 00:00 military time please)" wakeup = raw_input() wakeuphour = int(wakeup[:2]) wakeupmin = int(wakeup[3:]) now = datetime.datetime.now() if now.hour > wakeuphour or (now.hour == wakeuphour and now.minute > wakeupmin): alarmday = now + datetime.timedelta(days=1) alarmtime = datetime.datetime(alarmday.year,alarmday.month,alarmday.day,wakeuphour,wakeupmin) else: alarmtime = datetime.datetime(now.year,now.month,now.day,wakeuphour,wakeupmin) close = 15 grace = 5 alarm = Alarm(alarmtime, grace, close) if alarmtime.day != now.day: print "Your alarm is set for %02d:%02d tomorrow." % (alarmtime.hour,alarmtime.minute) else: print "Your alarm is set for %02d:%02d today." % (alarmtime.hour, alarmtime.minute) def runAlarm(): setAlarm() alarm.start() while True: print "You can say 'stop', 'check', 'change', 'set', or 'quit'" text = str(raw_input()) if text == "stop": if alarm != 0: alarm.just_die() alarm = 0 print "Okay, I've cancelled the alarm." else: print "There was no alarm to stop..." elif text == "check": if alarm == 0: print "Sorry, you don't have any alarm set. To create an alarm, type 'set'" else: pass elif text == "change": pass elif text == "set": alarm = 0 setAlarm() alarm.start() elif text == "quit": print "Sure thing. Bye bye!" break else: print "Sorry, I didn't understand that. Please try again."I'm trying to make a program that is effectively an alarm clock. It's more complicated than it might seem that it needs to be, but there are reasons for that, that I won't go into here. The issue I'm having, though, is that I create an Alarm object inside a nested function, but whatever I do, I can't get that object to be accessed outside of that function... I've attached the abridged code below. Any of the calls to "check" or "set" etc. outside of setAlarm can never find the "alarm" variable. Please let me know what I'm doing wrong — I tried declaring the variable as global, as you'll see, but it still doesn't work out...
Thanks!
class Alarm(threading.Thread): def __init__(self, datetime, grace, close): super(Alarm, self).__init__() self.datetime = datetime self.grace = grace self.close = close self.keep_running = True def run(self): try: while self.keep_running: now = datetime.datetime.now() if now > self.datetime + datetime.timedelta(minutes=self.grace): print "Oh no! It's %02d:%02d, which is %d minutes past your alarm time of %02d:%02d!" % (now.hour,now.minute,self.grace,self.datetime.hour,self.datetime.minute) print "ALARM NOW!\a\a\a\a\a\a\a\a\a\a" break time.sleep(10) except: return def just_die(self): self.keep_running = False def setAlarm(): print "What time would you like to set the alarm for? (in 00:00 military time please)" wakeup = raw_input() wakeuphour = int(wakeup[:2]) wakeupmin = int(wakeup[3:]) now = datetime.datetime.now() if now.hour > wakeuphour or (now.hour == wakeuphour and now.minute > wakeupmin): alarmday = now + datetime.timedelta(days=1) alarmtime = datetime.datetime(alarmday.year,alarmday.month,alarmday.day,wakeuphour,wakeupmin) else: alarmtime = datetime.datetime(now.year,now.month,now.day,wakeuphour,wakeupmin) close = 15 grace = 5 alarm = Alarm(alarmtime, grace, close) if alarmtime.day != now.day: print "Your alarm is set for %02d:%02d tomorrow." % (alarmtime.hour,alarmtime.minute) else: print "Your alarm is set for %02d:%02d today." % (alarmtime.hour, alarmtime.minute) def runAlarm(): setAlarm() alarm.start() while True: print "You can say 'stop', 'check', 'change', 'set', or 'quit'" text = str(raw_input()) if text == "stop": if alarm != 0: alarm.just_die() alarm = 0 print "Okay, I've cancelled the alarm." else: print "There was no alarm to stop..." elif text == "check": if alarm == 0: print "Sorry, you don't have any alarm set. To create an alarm, type 'set'" else: pass elif text == "change": pass elif text == "set": alarm = 0 setAlarm() alarm.start() elif text == "quit": print "Sure thing. Bye bye!" break else: print "Sorry, I didn't understand that. Please try again."最满意答案
您已将alarm创建为局部变量。 函数中定义的变量默认是局部的,而local本身就是它听起来的样子 - 它只存在于该函数内部。
您可以通过明确地将其作为全局变量来解决此问题。 这不是一个好主意,但它是最小的变化。 只需将语句global alarm添加到setAlarm的顶部以及要访问它的每个函数。
更好的解决方案是从setAlarm return alarm 。 然后,在调用它的代码中,只存储返回值。 例如:
def setAlarm(): # your existing code return alarm def runAlarm(): alarm = setAlarm() # your existing code现在, runAlarm有自己对同一对象的本地引用,也称为alarm ,因此它可以使用它。
You've created alarm as a local variable. Variables defined in a function are local by default, and local means exactly what it sounds like—it only exists inside that function.
You could fix this by explicitly making it a global variable. That's not a great idea, but it's the smallest change. Just add the statement global alarm to the top of both setAlarm and every function that wants to access it.
A better solution is to return alarm from setAlarm. Then, in the code that calls it, just store the return value. For example:
def setAlarm(): # your existing code return alarm def runAlarm(): alarm = setAlarm() # your existing codeNow, runAlarm has its own local reference to the same object, also named alarm, so it can use that.
更多推荐
发布评论