2014-09-21 30 views
0

我試圖製作一個實際上是鬧鐘的程序。它看起來比它看起來要複雜得多,但是有原因,我不會進入這裏。我遇到的問題是,我在嵌套函數中創建了一個Alarm對象,但無論我做什麼,我都無法讓該對象在該函數之外被訪問......我附加了刪節的代碼下面。 setAlarm外的任何「檢查」或「設置」等的調用都無法找到「報警」變量。請讓我知道我在做什麼錯了 - 我試圖將變量聲明爲全局變量,就像你會看到的那樣,但它仍然不能正常工作...在Python中嵌入函數之外訪問對象

謝謝!

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." 
+0

你問的是什麼嵌套函數?我根本沒有看到任何嵌套函數。 – abarnert 2014-09-21 00:19:13

+0

另外,你還有其他一些錯誤。例如,'alarm'是一個'Alarm'對象。它怎麼可能是'== 0'?除非你爲你的'Alarm'對象定義'__eq__'方法,否則它總是錯誤的。另外,你爲什麼要調用'str(raw_input())'? 'raw_input'函數總是返回一個字符串。你是否想要完成某些事情,比如從中獲得可打印的字符串表示?如果是這樣,你不是; 'str'什麼都不做。 – abarnert 2014-09-21 00:26:29

回答

0

您已創建alarm作爲局部變量。在函數中定義的變量默認是本地的,本地意味着它聽起來像 - 它只存在於該函數內。

可能通過明確地將其作爲全局變量來解決此問題。這不是一個好主意,但它是最小的變化。只需將語句global alarm添加到setAlarm以及想要訪問它的每個函數的頂部。

更好的解決方案是從setAlarmreturn alarm。然後,在調用它的代碼中,只存儲返回值。例如:現在

def setAlarm(): 
    # your existing code 
    return alarm 

def runAlarm(): 
    alarm = setAlarm() 
    # your existing code 

runAlarm都有自己的本地引用同一個對象,也叫alarm,所以它可以使用。

+0

完美,這是有道理的(兩個修復)。我從來沒有對「全球化」的使用表現得非常清楚;我不知道我必須將它放在兩個函數中,但這是有道理的。你提到的第二件事情似乎更容易。非常感謝!! – dangr 2014-09-21 03:34:10