NameError: 全局名称 'message' 未定义

2 投票
1 回答
12734 浏览
提问于 2025-04-17 14:53

我刚开始学习Python,目前正在做一个GPS追踪器,这个追踪器可以和谷歌地图互动,我是用Arduino Uno来实现的。现在我遇到了一个错误,导致我无法运行我的tcpServer的.py脚本,这就是我的整个脚本。

#!/usr/bin/env python

import socket
import MySQLdb

TCP_IP = 'my machine IP'
TCP_PORT = 32000
BUFFER_SIZE = 40

# ClearDB. Deletes the entire tracking table

def ClearDB(curs,d ):
    curs.execute ("""
        INSERT INTO gmaptracker (lat, lon)
        VALUES (0.0,0.0)""")
    d.commit()

# Connect to the mySQL Database

def tServer():
    try:

        db = MySQLdb.connect (host = "my host",
            user = "my user",
            passwd = "my password",
            db = "gmap" )
    except MySQLdb.Error, e:
        print "Error %d: %s" %(e.args[0], e.args[1])
        sys.exit(1);

    cursor = db.cursor()

    # Start with a fresh tracking table

    ClearDB(cursor,db)

    # Set up listening Socket

    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((TCP_IP, TCP_PORT))
        print "Listening...."
        s.listen(1)
        conn, addr = s.accept()
        print 'Accepted connection from address:', addr

    except socket.error (message):
        if s:
            s.close()
            print "Could not open socket: " + message
            cursor.close()
            conn.close()
            db.close()
            sys.exit(1)

    try:
        while 1:
            data = conn.recv(BUFFER_SIZE)
            if not data:break

            str1,str2 = data.split("Long: ")
            str1 = str1.split("Lat: ")[1]
            latitude = float(str1)
            longitude = float(str2)
            cursor.execute ("""
                INSERT INTO gmaptracker (lat, lon)
                VALUES (%s,%s)""", (latitude,longitude))

            db.commit()

    except KeyboardInterrupt:
        ClearDB(cursor,db);
        cursor.close()
        conn.close()
        db.close()

if __name__ == '__main__':
   tServer()

这是我遇到的错误信息。

Traceback (most recent call last):
 File "tcpServer.py", line 79, in <module>
   tServer()
 File "tcpServer.py", line 48, in tServer
   except socket.error(message):
NameError: global name 'message' is not defined

如果有人能帮我解决这个问题,我会非常感激。正如我所说,我对Python还不太熟悉,我现在使用的是Python 2.7,希望这能有所帮助。提前谢谢大家!

1 个回答

2

你在捕获异常时使用的语法不对。应该这样写:

except socket.error as serror:
    message = serror.message

socket.error 异常有两个额外的属性,分别是 errnomessage。以前的代码是这样捕获它的:

except socket.error, (value, message):

因为在 Python 2 中,你可以把异常当作元组来处理并解包,但在 Python 3 中这个功能已经被去掉了,所以不应该再使用。

而且,之前的 except exceptiontype, targetvariable: 语法已经被 except exceptiontype as targetvariable: 替代了,这样在同一句话中捕获多个异常类型时会更清晰。

当抛出异常时,正常的代码流程会被打断;流程会“跳”到异常处理程序那里。因为这个跳转,你的代码中会出现另一个问题。在异常处理程序中你提到了 conn.close(),但变量 conn 是在抛出 socket 异常的地方之后才定义的(也就是各种 socket 操作)。这会导致出现 NameError。在这种情况下,代码中没有任何路径会让 conn 被赋值为一个打开的 socket 连接,所以你可以完全删除 conn.close() 这一行。

如果真的需要对 conn 调用 .close(),你需要先检查它是否已经被设置。可以提前把它设置为 None,然后只有在 conn 不再是 None 的时候才调用 .close()

conn = None
try:
    # ... do stuff ...
    conn, addr = s.accept()
    # ... do more stuff
except socket.error as serror:
    # test if `conn` was set
    if conn is not None:
        conn.close()

撰写回答