2012-07-18 56 views
1

我是一個完整的Python n00b在這裏,只是試圖搗碎幾個位在一起,使一個項目的工作,但我掙扎着一些我認爲的語法。從每個循環Python未定義函數

這裏是我的劇本我到目前爲止有:

#!/usr/bin/env python 

from plugin import * 
from siriObjects.systemObjects import ResultCallback 
import uuid 
import json 
import random 
import types 
import urllib 
import urllib2 
import random 
import re 
import select 
import socket 
import struct 
import sys 
import thread 
import time 

class tivoRemote(Plugin): 

     tivo_address = '192.168.0.9' 
     tivo_name = '' 
     tivo_swversions = {} 
     have_zc = True 
     captions_on = False 
     sock = None 
     outer = None 


     def connect(): 
      """ Connect to the TiVo within five seconds or report error. """ 
      global sock 
      try: 
       sock = socket.socket() 
       sock.settimeout(5) 
       sock.connect((tivo_address, 31339)) 
       sock.settimeout(None) 
      except Exception, msg: 
       msg = 'Could not connect to %s:\n%s' % (tivo_name, msg) 
       print(msg) 

     def send(message): 
      """ The core output function, called from irsend(). Re-connect if 
       necessary (including restarting the status_update thread), send 
       message, sleep, and check for errors. 
       """ 

      if not sock: 
       self.connect() 
       thread.start_new_thread(status_update,()) 
      try: 
       sock.sendall(message) 
       time.sleep(0.1) 
      except Exception, msg: 
       error_window(str(msg)) 


     def irsend(*codes): 
      """ Expand a command sequence for send(). """ 
      for each in codes: 
       self.send('IRCODE %s\r' % each) 


     @register("en-US", ".*Change.*Channel.*") 
     def channelChanger(self, speech, language, matchedRegex): 
       if language == 'en-US': 
         answer = self.ask(u"Which channel would you like?") 
         self.say(u"Ok, one moment..".format(answer)) 
         self.connect() 
         self.irsend(answer) 
       self.complete_request() 

,我得到的錯誤是:

Traceback (most recent call last): 
    File "/home/pi/SiriServerCore/plugin.py", line 150, in run 
    self.__method(self, self.__speech, self.__lang,  self.__method.__dict__[__criteria_key__][self.__lang].match(self.__speech)) 
    File "/home/pi/SiriServerCore/plugins/tivoRemote/__init__.py", line 70, in  channelChanger 
    self.irsend(format(answer)) 
    File "/home/pi/SiriServerCore/plugins/tivoRemote/__init__.py", line 61, in irsend 
    self.send('IRCODE %s\r' % each) 
NameError: global name 'self' is not defined 

如果我刪除了 '自我'。我得到同樣的錯誤,但說'發送'沒有定義。

預先感謝任何幫助:) 瑞安

+1

我看到一個調用堆棧,但沒有錯誤。你能否用錯誤更新你的問題? :) – 2012-07-18 15:39:29

+1

不應該類方法有'self'作爲第一個參數? – 2012-07-18 15:39:44

+2

@LevLevitsky:不,但實例方法應該。 – geoffspear 2012-07-18 15:40:01

回答

3

更可能的工作:

class tivoRemote(Plugin): 

    def __init__(self): 
     self.tivo_address = '192.168.0.9' 
     self.tivo_name = '' 
     self.tivo_swversions = {} 
     self.have_zc = True 
     self.captions_on = False 
     self.sock = None 
     self.outer = None 


    def connect(self): 
     """ Connect to the TiVo within five seconds or report error. """ 
     try: 
      sock = socket.socket() 
      sock.settimeout(5) 
      sock.connect((tivo_address, 31339)) 
      sock.settimeout(None) 
     except Exception, msg: 
      msg = 'Could not connect to %s:\n%s' % (tivo_name, msg) 
      print(msg) 
     self.sock = sock 

    def send(self, message): 
     """ The core output function, called from irsend(). Re-connect if 
      necessary (including restarting the status_update thread), send 
      message, sleep, and check for errors. 
     """ 

     if not self.sock: 
      self.connect() 
      thread.start_new_thread(status_update,()) # status_update must be some global at this point 
     try: 
      self.sock.sendall(message) 
      time.sleep(0.1) 
     except Exception, msg: 
      error_window(str(msg)) 


    def irsend(self, *codes): 
     """ Expand a command sequence for send(). """ 
     for each in codes: 
      self.send('IRCODE %s\r' % each) 


    @register("en-US", ".*Change.*Channel.*") 
    def channelChanger(self, speech, language, matchedRegex): 
      if language == 'en-US': 
        answer = self.ask(u"Which channel would you like?") 
        self.say(u"Ok, one moment..".format(answer)) 
        self.connect() 
        self.irsend(answer) 
      self.complete_request() 

您需要定義方法時使用self,你必須使用它來訪問當前實例。

+0

我推薦:def connect(self):or @staticmethod \ ndef connect(): – DevPlayer 2012-07-18 15:51:16

+0

謝謝!和其他建議相同的人:) – bulldog5046 2012-07-18 15:52:02

1

您需要定義所有實例方法(你有self.訪問)與self作爲第一個參數,你會習慣它:

class tivoRemote(Plugin): 

    tivo_address = '192.168.0.9' 
    tivo_name = '' 
    tivo_swversions = {} 
    have_zc = True 
    captions_on = False 
    sock = None 
    outer = None 


    def connect(self): 
     """ Connect to the TiVo within five seconds or report error. """ 
     global sock 
     try: 
      sock = socket.socket() 
      sock.settimeout(5) 
      sock.connect((tivo_address, 31339)) 
      sock.settimeout(None) 
     except Exception, msg: 
      msg = 'Could not connect to %s:\n%s' % (tivo_name, msg) 
      print(msg) 

    def send(self, message): 
     """ The core output function, called from irsend(). Re-connect if 
      necessary (including restarting the status_update thread), send 
      message, sleep, and check for errors. 
      """ 

     if not sock: 
      self.connect() 
      thread.start_new_thread(status_update,()) 
     try: 
      sock.sendall(message) 
      time.sleep(0.1) 
     except Exception, msg: 
      error_window(str(msg)) 


    def irsend(self, *codes): 
     """ Expand a command sequence for send(). """ 
     for each in codes: 
      self.send('IRCODE %s\r' % each) 


    @register("en-US", ".*Change.*Channel.*") 
    def channelChanger(speech, language, matchedRegex): 
      if language == 'en-US': 
        answer = self.ask(u"Which channel would you like?") 
        self.say(u"Ok, one moment..".format(answer)) 
        self.connect() 
        self.irsend(answer) 
      self.complete_request() 

此外,如果你想要那些屬性屬於實例,而不是類(如靜態屬性),則必須在構造中定義它們(__init__,這是最接近構造的東西):

class tivoRemote(Plugin): 
    def __init__(self): 
     self.tivo_address = '192.168.0.9' 
     self.tivo_name = '' 
     self.tivo_swversions = {} 
     self.have_zc = True 
     self.captions_on = False 
     self.sock = None 
     self.outer = None 
1

您正在創建的成員變量屬於類而不是實例(您在類中定義變量的方式)。如果要從實例中調用send()等方法,則這些函數的第一個參數必須是self。你會需要修改你的整個代碼是這樣的:

class tivoRemote(..): 
    def __init__(self): 
     self.tivo_address = '192.168.0.9' 
     self.tivo_name = '' #and so on for other members 
     .... 

    def send(self, msg): 
     self.connect() 
     self.sendall(..) 

    def connect(self, ...): 
     #self.sock 
     self.sock = socket.socket() 
     .... 

    #and similar for all other method that you think is a part of "instance" add the 
    #first parameter as self 
0

解釋:

class MyThing(object): 
    """I am a class definition 

    Everything here is part of the class definition. 

    Methods here are classmethods, they are considered "unbound" 

    When you create an instance of this class like so: 
     my_instance_of_class_MyThing = MyThing() 

    the "my_instance_of_class_MyThing" now points to an object. 

    that object is an instance object. 

    that object is an instance object of MyThing 

    the "my_instance_of_class_MyThing" now points to an instance object. 

    the methods contained in the instance object are NOW "bound" to the instance 

    bound methods are bound to an instance object 

    bound methods are sent a reference to the thing they are bound too by 
     python itself when they are called. 
    """ 

    i_am_a_class_attribute = "I am a class attribute" 

    def __init__(self): 

     """ I am a method. I start my life as a class method unbound to 
     any instance. Because I am unbound, when you call me I will 
     complain to you in the form of an unbound exception call, thus 
     likely crashing your application. 

     When you create an instance the class I was defined in, 
     I will copy a bound copy of myself into the newly created instance. 
     When you call the bound copy of myself, Python will politely send 
     a reference of the instance object to the bound method as its 
     very first argument. Many people name that varible "self". Some use 
     "me". Others programmers break with convention and use a 
     single character, but this is rare. 
     """ 


     i_am_a_init_local_reference_to = 
      "this string and only visible with in __init__()" 


     # self is a variable name python sends to mything_instance.__init__() as the first argument 
     # self points to the same thing mything_instance points to, 
     #  an INSTANCE of the class MyThing 

     self.i_am_an_instance_reference_to = 
      '''this string and is visible to everthing that can access what "self" points too.''' 


    def proof(self): 
     try: 
      print i_am_a_init_local_reference_to 
     except AttributeError, error_message: 
      print error_message 
     else: 
      print "This won't happen !!" 
      print "It successfully printed i_am_a_init_local_reference_to" 

     try: 
      print self.i_am_an_instance_reference_to 
     except AttributeError, error_message: 
      print error_message 
     else: 
      print """See proof() can access self.i_am_an_instance_reference_to""" 

希望這有助於那些不知道爲什麼解決方案,其中給出。