Python线程模块错误:'NoneType'对象不可调用

3 投票
1 回答
4931 浏览
提问于 2025-04-17 21:04

我运行下面的代码时,屏幕上显示了 <type 'exceptions.TypeError'>: 'NoneType' object is not callable 这个错误:

import threading
import urllib2
import Queue
import time

hosts = ["http://baidu.com", "http://yahoo.com"]

queue = Queue.Queue()

class ThreadUrl(threading.Thread):
    """ Threaded Url Grab """
    def __init__(self, queue):
        threading.Thread.__init__(self)
        self.queue = queue

    def run(self):
        while True:
            #grabs host from queue
            host = self.queue.get()

            #grabs urls of hosts and prints first 1024 byte of page
            url = urllib2.urlopen(host)

            #signals to queue job is done
            self.queue.task_done()

start = time.time()
def main():
    for i in range(2):
        t = ThreadUrl(queue)
        t.setDaemon(True)
        t.start()

        for host in hosts:
            queue.put(host)

    queue.join()

main()
print "Elapsed Time: %s" % (time.time() - start)

这是错误的详细信息:

Exception in thread Thread-3 (most likely raised during interpreter shutdown):
Traceback (most recent call last):
File "/usr/local/lib/python2.7/threading.py", line 808, in __bootstrap_inner
File "url_thread.py", line 21, in run
File "/usr/local/lib/python2.7/Queue.py", line 168, in get
File "/usr/local/lib/python2.7/threading.py", line 332, in wait
<type 'exceptions.TypeError'>: 'NoneType' object is not callable

我的代码哪里出问题了?非常感谢。

1 个回答

2

这是一个关于Python 2.7的错误 - 守护线程中的关闭异常。你可以把线程设置为非守护线程,然后通过队列传递一个信号,告诉它们退出,最后在主线程中等待它们结束。

import threading
import urllib2
import Queue
import time

hosts = ["http://baidu.com", "http://yahoo.com"]

queue = Queue.Queue()

class ThreadUrl(threading.Thread):
    """ Threaded Url Grab """
    def __init__(self, queue):
        threading.Thread.__init__(self)
        self.queue = queue

    def run(self):
        while True:
            #grabs host from queue
            host = self.queue.get()
            if host is None:
                self.queue.task_done()
                return

            #grabs urls of hosts and prints first 1024 byte of page
            url = urllib2.urlopen(host)

            #signals to queue job is done
            self.queue.task_done()

start = time.time()
def main():
    threads = [ThreadUrl(queue) for _ in range(2)]
    map(lambda t: t.start() threads)
    for i in range(2):
        for host in hosts:
            queue.put(host)
    for t in threads:
        queue.put(None)
    queue.join()
    map(lambda t: t.join() threads)

main()
print "Elapsed Time: %s" % (time.time() - start)

撰写回答