Python "variable not defined" error

112 阅读2分钟

在使用Python编写代码时,用户遇到了一个错误提示“NameError: name 'messages' is not defined”,这是因为在调用write_csv函数时,它试图使用“messages”变量,但该变量在函数之外没有被定义。以下代码展示了这个问题:

import csv
import json
import oauth2 as oauth
import urllib
import sys
import requests
import time

CONSUMER_KEY = ""
CONSUMER_SECRET = ""
ACCESS_KEY = ""
ACCESS_SECRET = ""

class TwitterSearch:
    def __init__(self,
        ckey    = CONSUMER_KEY,
        csecret = CONSUMER_SECRET,
        akey    = ACCESS_KEY,
        asecret = ACCESS_SECRET,
        query   = 'https://api.twitter.com/1.1/search/tweets.{mode}?{query}'
    ):
        consumer     = oauth.Consumer(key=ckey, secret=csecret)
        access_token = oauth.Token(key=akey, secret=asecret)
        self.client  = oauth.Client(consumer, access_token)
        self.query   = query

    def search(self, q, mode='json', **queryargs):
        queryargs['q'] = q
        query = urllib.urlencode(queryargs)
        return self.client.request(self.query.format(query=query, mode=mode))

def write_csv(fname, rows, header=None, append=False, **kwargs):
    filemode = 'ab' if append else 'wb'
    with open(fname, filemode) as outf:
        out_csv = csv.writer(outf, **kwargs)
        if header:
            out_csv.writerow(header)
        out_csv.writerows(rows)

def main():
    ts = TwitterSearch()
    response, data = ts.search('@gmail.com', result_type='recent')
    js = json.loads(data)

    messages = ([msg['created_at'], msg['txt'], msg['user']['id']] for msg in js.get('statuses', []))

write_csv('twitter_gmail.csv', messages, append=True)  # Error: 'messages' is not defined

if __name__ == '__main__':
    main()

当运行这段代码时,你会看到以下错误:

Traceback (most recent call last):
  File "./twitter_test16.sh", line 53, in <module>
    write_csv('twitter_gmail.csv', messages, append=True)
NameError: name 'messages' is not defined

2. 解决方案

解决这个问题非常简单,只需要将write_csv函数的调用移到main()函数内部,同时将messages变量移出main()函数:

import csv
import json
import oauth2 as oauth
import urllib
import sys
import requests
import time

CONSUMER_KEY = ""
CONSUMER_SECRET = ""
ACCESS_KEY = ""
ACCESS_SECRET = ""

class TwitterSearch:
    def __init__(self,
        ckey    = CONSUMER_KEY,
        csecret = CONSUMER_SECRET,
        akey    = ACCESS_KEY,
        asecret = ACCESS_SECRET,
        query   = 'https://api.twitter.com/1.1/search/tweets.{mode}?{query}'
    ):
        consumer     = oauth.Consumer(key=ckey, secret=csecret)
        access_token = oauth.Token(key=akey, secret=asecret)
        self.client  = oauth.Client(consumer, access_token)
        self.query   = query

    def search(self, q, mode='json', **queryargs):
        queryargs['q'] = q
        query = urllib.urlencode(queryargs)
        return self.client.request(self.query.format(query=query, mode=mode))

def write_csv(fname, rows, header=None, append=False, **kwargs):
    filemode = 'ab' if append else 'wb'
    with open(fname, filemode) as outf:
        out_csv = csv.writer(outf, **kwargs)
        if header:
            out_csv.writerow(header)
        out_csv.writerows(rows)

def main():
    ts = TwitterSearch()
    response, data = ts.search('@gmail.com', result_type='recent')
    js = json.loads(data)

    messages = ([msg['created_at'], msg['txt'], msg['user']['id']] for msg in js.get('statuses', []))
    write_csv('twitter_gmail.csv', messages, append=True)

if __name__ == '__main__':
    main()

这样,messages变量就会在main()函数中被定义,然后在write_csv函数中被使用,就不会出现错误。

需要注意的是,为了确保代码能够正确运行,你还需要在代码中填入实际的API密钥和访问令牌,这些密钥和令牌可以从Twitter开发者平台获取。