如何解决在实例化队列之前缺少 multiprocessing.queue 模块
我正在为女巫 Queues
工作,一切似乎都很顺利。但是,我发现一种情况会导致意外的 AttributeError
异常出现。
让我们创建最简单的代码来创建 Queue
。不用担心它的用法,这一切都发生在同一端,我们不必担心另一端会与之通信。
import multiprocessing
q = multiprocessing.Queue()
print(type(q))
<class 'multiprocessing.queues.Queue'>
但是如果我尝试确定对象是否是此类的实例会发生什么?
isinstance(q,multiprocessing.queues.Queue)
显然它返回 True
。
最后,我的问题由此而产生,如果我在检查之前不创建 Queue
实例,则不会加载定义了 multiprocessing.queues
的模块 Queue
! (警告,因为我们谈论的是模块,所以这里可能不适合使用加载这个词。我不是这方面的专家)让我们检查一下:
import multiprocessing
a = dict()
isinstance(a,multiprocessing.queues.Queue)
出乎意料的是我们失败的地方:
1 isinstance(a,multiprocessing.queues.Queue)
AttributeError: module 'multiprocessing' has no attribute 'queues'
为什么会这样?这是预期的行为还是这种错误?
对我来说,这代表了一个问题,因为如果我想检查一个对象是否是 Queue
而它不是,如果没有其他队列被实例化,我的检查可能以不希望的 AttributeError
结束.
最后,我想添加一张快速图片,其中包含一些我复制的检查结果,并为 queues
内的 multiprocessing.__all__
模块添加了一些检查。
这些检查已在 Python 3.9.1 中执行。值得注意的是,当 multiprocessing.queues
已经被识别并因此检查没有抛出 AttributeError
时,queues
出现在 multiprocessing.__dict__
中。在其他情况下,则不是。
这对专家来说似乎很自然,因为 __dict__
是(AFAIK)属性列表,但我想指出它,因为我说过我不是专家,我不知道它的实际影响。
附注。我已将问题标记为 Python 3.8
,因为它已经在 3.8
和 3.9
中进行了测试并得到了相同的结果,如果存在差异,我希望得到 {{1} 的答案}.这些差异可能是由于多处理库的变化而出现的,因为文档反映在函数末尾的几个脚注中。
PS.2。由于 3.8
的输出,我一直将 multiprocessing.queues
称为模块。再说一次,我不是这方面的专家:
multiprocessing.__dict__
解决方法
这是有意的行为。如果你想访问一个子模块,你应该导入它:
import multiprocessing.queues
a = dict()
isinstance(a,multiprocessing.queues.Queue)
导入子模块会将它们作为属性添加到其父模块中 – 请注意 multiprocessing.queues.Queue
是如何在 Queue
上的 queue
上的 queue
上的嵌套属性查找 multiprocessing
.显式导入可确保在访问子模块之前加载它。
导入系统:5.4.2. Submodules
当使用任何机制(例如 importlib
API、import
或 import-from
语句或内置 __import__()
)加载子模块时,绑定被放置在父模块的命名空间到子模块对象。例如,如果包 spam
有一个子模块 foo
,那么在导入 spam.foo
后,spam
将有一个属性 foo
绑定到子模块。>
这意味着当另一个操作作为副作用导入子模块时,可以避免跳过显式导出。与所有副作用一样,人们必须实际执行触发动作才能依赖副作用。
由于导入是幂等的(重复导入不会产生不良影响),因此应该导入任何希望访问的模块,而不是依赖其他代码的副作用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。