首页 > 解决方案 > 导入一个未打包模块的python类,并在它自己的线程中运行

问题描述

这个 Stack Overflow 答案详细说明了如何使用 importlib 导入模块,并检查以按名称查找包含的类。

虽然这在用于执行模块时有效,但在线程中运行完全相同的代码时spec.loader.exec_module(module)无法找到“MyClass” ,如下所示:modulethreading.Thread(target=spec.loader.exec_module, args=[module])

我已经设置了一个可以运行的工作示例,以简单的方式查看此效果,只需将以下内容复制到两个文件中并执行第一个文件即可。

文件 1:

# test1.py

import importlib.util
import inspect
import threading

my_file = 'thread_test'
path = "thread_test.py"

spec = importlib.util.spec_from_file_location(my_file, path)
module = importlib.util.module_from_spec(spec)

# Comment out one of the following snippets to test each version:

# OPTION 1:
# Non-Threaded Version, Works:
spec.loader.exec_module(module)

# OPTION 2:
# Threaded Version, Doesn't work (Causes cls to not be found in the following loop):
# thread = threading.Thread(target=spec.loader.exec_module, args=[module])
# thread.start()

cls = None
for member in inspect.getmembers(module):
    if member[0] == 'MyClass':
        cls = member[1]

cls.color = 'blue'

cls().PrintColor()

文件 2:

# thread_test.py

class MyClass:
    color = None
    
    def PrintColor(self):
        print(self.color)

为什么模块在它自己的线程中执行时不包含 MyClass,但它却在同一个线程中执行?

标签: pythonmultithreadingpython-multithreading

解决方案


您只启动了线程,但您必须加入它并等待它运行:thread.join()。否则模块将无法正确导入。

完整示例:

import importlib.util
import inspect
import threading

my_file = 'thread_test'
path = "thread_test.py"

spec = importlib.util.spec_from_file_location(my_file, path)
module = importlib.util.module_from_spec(spec)

# Comment out one of the following snippets to test each version:

# OPTION 1:
# Non-Threaded Version, Works:
# spec.loader.exec_module(module)

# OPTION 2:
# Threaded Version, Doesn't work (Causes cls to not be found in the following loop):
thread = threading.Thread(target=spec.loader.exec_module, args=[module])
thread.start()
thread.join()

cls = None
for member in inspect.getmembers(module):
    if member[0] == 'MyClass':
        cls = member[1]

cls.color = 'blue'

cls().PrintColor()

结果:

blue


推荐阅读