简体   繁体   中英

def in python not working when called

import pyttsx 
import random
import os  
import serial
import webbrowser

while True:
    def portport():
        ser = serial.Serial('COM3',9600) 
        raw_data = ser.read(7)
        msg = str(raw_data[3:6])
        print msg
        ser.close()

    engine = pyttsx.init()
    portport()
    if(msg == 'mof'):
            engine.say('Are you sure?')   
            engine.runAndWait()          
            portport()
            if(msg == 'yes'):
                engine.say('Chrome has now closed')
                os.system("TASKKILL /F /IM chrome.exe")
                engine.runAndWait()

            elif(msg == 'noo'):
                engine = pyttsx.init()
                engine.say('Are you kidding me?')
                engine.runAndWait()

    if(msg == 'hi_'):
            greeting()
    if(msg == 'bye'):
            leaving()
    if(msg == 'who'):
            engine = pyttsx.init()
            engine.say('Hi there')
            engine.runAndWait()

    if(msg == 'lik'):
           engine = pyttsx.init()
           engine.say('Ofcourse I do!')
           engine.runAndWait()

My problem is that everything works if instead of creating a def ( portport() ) and call it when I need it, I just write my code which is included in this def. I used (but didn't put in here because I don't want it to be a very long piece of code) other functions (for example greeting() ) and it worked just fine.

Eclipse's console when using the code as above "says":

Traceback (most recent call last):
  File "C:\Users\xxx\eclipse\workspace\Ai_Project\Ai\Ai_Brain.py", line 126, in <module>
    if(msg == 'mof'):
NameError: name 'msg' is not defined

And every single if(msg == 'something'): turns red

I have read a lot of posts here and everywhere but can't seem to be a python function problem

THE ANSWER: Thank you all for your valuable answers and a little bit more for mhawke's answer. The code worked after the chances which had to be made according to your suggestions. For future use the updated code is:

.....

    def portport():

            ser = serial.Serial('COM3',9600) 
            raw_data = ser.read(7)
            msg = str(raw_data[3:6])
            print msg
            ser.close()
            return msg

    while True:

            engine = pyttsx.init() 

            msg = portport()

             if(msg == 'mof'):
                        engine.say('Are you sure?')   
                        engine.runAndWait()          
                        msg = portport()

                        if(msg == 'yes'):
                            engine.say('Chrome has now closed')
                            os.system("TASKKILL /F /IM chrome.exe")
                            engine.runAndWait()

                        elif(msg == 'noo'):
                            engine = pyttsx.init()
                            engine.say('Are you kidding me?')
                            engine.runAndWait()
                                                                      ......

msg is only defined within the portport function. If you want to use it outside, you need to return it from there, and assign it to a local variable.

Note, you should not have your function definition within the while loop.

def portport():
    ser = serial.Serial('COM3',9600) 
    raw_data = ser.read(7)
    msg = str(raw_data[3:6])
    print msg
    ser.close()
    return msg

while True:
    engine = pyttsx.init()
    msg = portport()
    if msg == 'mof':
        ...

Also note, you don't need parentheses around conditions in Python.

msgportport()局部变量,因此无法在外部访问。

Your msg variable is not in the correct scope.

import pyttsx 
import random
import os  
import serial
import webbrowser

while True:


    def portport():

        ser = serial.Serial('COM3',9600) 
        raw_data = ser.read(7)
        msg = str(raw_data[3:6])
        print msg
        ser.close()
        return msg

    engine = pyttsx.init()

    msg = portport()

    if(msg == 'mof'):

            engine.say('Are you sure?')   

            engine.runAndWait()          

            portport()

            if(msg == 'yes'):

                engine.say('Chrome has now closed')

                os.system("TASKKILL /F /IM chrome.exe")

                engine.runAndWait()


            elif(msg == 'noo'):

                engine = pyttsx.init()

                engine.say('Are you kidding me?')

                engine.runAndWait()

    if(msg == 'hi_'):

            greeting()

    if(msg == 'bye'):

            leaving()     

    if(msg == 'who'):

            engine = pyttsx.init()
            engine.say('Hi there')
            engine.runAndWait()

    if(msg == 'lik'):

           engine = pyttsx.init()
           engine.say('Ofcourse I do!')
           engine.runAndWait()

The problem is that when using the function, msg is a local variable of portport() . The variable is not available outside of the function. Therefore the references to it from outside the function cause the NameError exception.

When declared in line msg has the same scope as the references to it in the if statements, so there is no problem.

One way to correct this when using the function is to have the function return the value of msg :

def portport():
    ser = serial.Serial('COM3',9600) 
    raw_data = ser.read(7)
    msg = str(raw_data[3:6])
    print msg
    ser.close()
    return msg

Then call portport() and assign the return value to the variable msg :

msg = portport()

Now a new variable msg is created in the same scope as the if statements that reference it.

NB do not confuse the msg inside the function with that outside the function - they are different variables because they exist in different scopes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM