Python 中 NameError 全局名称未定义

NameError: name 'x' is not defined 是 Python 中常见的错误之一,通常表示你尝试访问一个尚未定义的变量或函数。特别是全局名称未定义时,意味着你在使用某个全局变量或函数时,Python 在当前命名空间中找不到该名称。

在这里插入图片描述

1、问题背景

在使用 Python 时,如果遇到了 NameError: global name ‘control_queue’ is not defined 的错误,通常是因为尝试访问一个尚未定义的全局变量。这种情况常见于多线程或多进程编程中,因为不同线程或进程可能无法访问彼此的局部变量。

在下面示例的代码中,control_queue 变量在函数 halt_listener 中被使用,但是它并没有在函数外部定义。这就会导致 NameError: global name ‘control_queue’ is not defined 的错误。

2、解决方案

要解决此问题,需要在函数外部定义 control_queue 变量,或者将 control_queue 传递给 halt_listener 函数作为参数。

2.1 将 control_queue 定义为全局变量
import multiprocessing
import time
from threading import Thread

class test_imports:#Test classes remove
    alive = {'import_1': True, 'import_2': True};

    def __init__(self, control_queue):
        self.control_queue = control_queue

    def halt_listener(self, thread_Name, kill_command):
          while True:
              print ("Checking queue for kill")
              isAlive = self.control_queue.get()
              print ("isAlive", isAlive)
              if isAlive == kill_command:
                 print ("kill listener triggered")
                 self.alive[thread_Name] = False;
                 return

    def import_1(self, thread_Number):
          print ("Import_1 number %d started") % thread_Number
          halt = test_imports()
          t = Thread(target=halt.halt_listener, args=(control_Queue, 'import_1', 't1kill'))
          count = 0
          t.run()
          global alive
          run = test_imports.alive['import_1'];
          while run:
                print ("Thread type 1 number %d run count %d") % (thread_Number, count)
                count = count + 1
                print ("Test Import_1 ", run)
                run = self.alive['import_1'];
          print ("Killing thread type 1 number %d") % thread_Number

    def import_2(self, thread_number):
          print ("Import_2 number %d started") % thread_number
          count = 1
          while True:
                alive = self.control_queue.get()
                count = count + 1
                if alive == 't2kill':
                   print ("Killing thread type 2 number %d") % thread_number
                   return
                else:
                     print ("Thread type 2 number %d run count %d") % (thread_number, count)

class worker_manager:
     def __init__(self):
        self.children = {}

     def generate(self, control_queue, threadName, runNum):
        i = test_imports(control_queue)
        if threadName == 'one':
            print ("Starting import_1 number %d") % runNum
            p = multiprocessing.Process(target=i.import_1, args=(runNum,))
            self.children[threadName] = p
            p.start()
        elif threadName == 'two':
            print ("Starting import_2 number %d") % runNum
            p = multiprocessing.Process(target=i.import_2, args=(runNum,))
            self.children[threadName] = p
            p.start()
        elif threadName == 'three':
            p = multiprocessing.Process(target=i.import_1, args=(runNum,))
            print ("Starting import_1 number %d") % runNum
            p2 = multiprocessing.Process(target=i.import_2, args=(runNum,))
            print ("Starting import_2 number %d") % runNum
            self.children[threadName] = p
            self.children[threadName] = p2
            p.start()
            p2.start()

        else:
            print ("Not a valid choice choose one two or three")

     def terminate(self, threadName):
         self.children[threadName].join

if __name__ == '__main__':
    # Establish communication queues
    control_queue = multiprocessing.Queue()
    manager = worker_manager()

    runNum = int(raw_input("Enter a number: "))
    threadNum = int(raw_input("Enter number of threads: "))
    threadName = raw_input("Enter number: ")
    thread_Count = 0

    print ("Starting threads")

    for i in range(threadNum):
        manager.generate(control_queue, threadName, i)
        thread_Count = thread_Count + 1

    time.sleep(runNum)#let threads do their thing

    print ("Terminating threads")

    for i in range(thread_Count):
        control_queue.put("t1kill")
        control_queue.put("t2kill")

    manager.terminate(threadName)
2.2 将 control_queue 传递给 halt_listener 函数作为参数
import multiprocessing
import time
from threading import Thread

class test_imports:#Test classes remove
    alive = {'import_1': True, 'import_2': True};

    def halt_listener(self, control_queue, thread_Name, kill_command):
          while True:
              print ("Checking queue for kill")
              isAlive = control_queue.get()
              print ("isAlive", isAlive)
              if isAlive == kill_command:
                 print ("kill listener triggered")
                 self.alive[thread_Name] = False;
                 return

    def import_1(self, control_queue, thread_Number):
          print ("Import_1 number %d started") % thread_Number
          halt = test_imports()
          t = Thread(target=halt.halt_listener, args=(control_queue, 'import_1', 't1kill'))
          count = 0
          t.run()
          global alive
          run = test_imports.alive['import_1'];
          while run:
                print ("Thread type 1 number %d run count %d") % (thread_Number, count)
                count = count + 1
                print ("Test Import_1 ", run)
                run = self.alive['import_1'];
          print ("Killing thread type 1 number %d") % thread_Number

    def import_2(self, control_queue, thread_number):
          print ("Import_2 number %d started") % thread_number
          count = 1
          while True:
                alive = control_queue.get()
                count = count + 1
                if alive == 't2kill':
                   print ("Killing thread type 2 number %d") % thread_number
                   return
                else:
                     print ("Thread type 2 number %d run count %d") % (thread_number, count)

class worker_manager:
     def __init__(self):
        self.children = {}

     def generate(self, control_queue, threadName, runNum):
        i = test_imports()
        if threadName == 'one':
            print ("Starting import_1 number %d") % runNum
            p = multiprocessing.Process(target=i.import_1, args=(control_queue, runNum))
            self.children[threadName] = p
            p.start()
        elif threadName == 'two':
            print ("Starting import_2 number %d") % runNum
            p = multiprocessing.Process(target=i.import_2, args=(control_queue, runNum))
            self.children[threadName] = p
            p.start()
        elif threadName == 'three':
            p = multiprocessing.Process(target=i.import_1, args=(control_queue, runNum))
            print ("Starting import_1 number %d") % runNum
            p2 = multiprocessing.Process(target=i.import_2, args=(control_queue, runNum))
            print ("Starting import_2 number %d") % runNum
            self.children[threadName] = p
            self.children[threadName] = p2
            p.start()
            p2.start()

        else:
            print ("Not a valid choice choose one two or three")

     def terminate(self, threadName):
         self.children[threadName].join

if __name__ == '__main__':
    # Establish communication queues
    control_queue = multiprocessing.Queue()
    manager = worker_manager()

    runNum = int(raw_input("Enter a number: "))
    threadNum = int(raw_input("Enter number of threads: "))
    threadName = raw_input("Enter number: ")
    thread_Count = 0

    print ("Starting threads")

    for i in range(threadNum):
        manager.generate

最后总结

NameError 的出现通常意味着 Python 找不到你引用的变量或函数。为了避免这个错误,你可以:

  1. 确保变量或函数已定义。
  2. 在函数内部修改全局变量时,使用 global 声明。
  3. 在调用之前定义函数。
  4. 导入需要的模块。
  5. 检查拼写。
  6. 理解作用域的限制。

这些实践可以帮助你更有效地避免和解决 NameError

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值