在实例化队列之前缺少 multiprocessing.queue 模块 [英] multiprocessing.queue module is missing until a Queue is instanced

查看:99
本文介绍了在实例化队列之前缺少 multiprocessing.queue 模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Queues 工作,一切似乎都很顺利.但是,我发现一种情况会导致出现意外的 AttributeError 异常.

I was working witch Queues and everything seemed to go fine. However, I found a situation that makes an unexpected AttributeError exception to arise.

让我们创建最简单的代码来创建Queue.不用担心它的用法,这一切都发生在同一端,我们不必担心另一端会与之通信.

Let's create the simplest code to create a Queue. Don't worry about it's usage, it all happens in the same side, we don't have to worry about the other side that will communicate with it.

import multiprocessing

q = multiprocessing.Queue()
print(type(q))

此代码将作为输出产生:

This code will produce as output:

<class 'multiprocessing.queues.Queue'>

但是如果我尝试确定对象是否是此类的实例会发生什么?

But what happens if I try to identify if the object is an instance of this class?

isinstance(q, multiprocessing.queues.Queue)

显然它返回True.

最后,我的问题是因此而产生的,如果我在检查之前不创建 Queue 实例,模块 multiprocessing.queues where Queue 已定义,未加载!(警告,因为我们谈论的是模块,所以这里可能不适合使用加载这个词.我不是这方面的专家)让我们检查一下:

Finally, my question arose due to that, if I don't create a Queue instance before that checking, the module multiprocessing.queues where Queue is defined, is not loaded! (Warning, maybe loaded is not the appropriate word here since we are talking about modules. I'm not an expert on it) Let's check it:

import multiprocessing

a = dict()
isinstance(a, multiprocessing.queues.Queue)

出乎意料的是我们失败的地方:

Where surprisingly we get the failure:

 1 isinstance(a, multiprocessing.queues.Queue)

AttributeError: module 'multiprocessing' has no attribute 'queues'

为什么会这样?这是预期的行为还是这种错误?

对我来说,这代表了一个问题,因为如果我想检查一个对象是否是 Queue 而它不是,如果没有其他队列被实例化,我的检查可能以不需要的 AttributeError.

For me, this represents a problem because in case I want to check if an object is a Queue and it's not, if no other queue has been instanced my check could end in an undesired AttributeError.

最后,我想添加一个快速图片,其中包含一些我复制的检查,并在 multiprocessing.__all__ 中添加了一些对 queues 模块的检查.

Finally, I would like to add a quick picture with some checks that I did reproducing this, plus adding some checks for the queues module inside the multiprocessing.__all__.

这些检查已在 Python 3.9.1 中执行.值得注意的是,当 multiprocessing.queues 已经被识别并且因此检查没有抛出 AttributeError 时,queues 出现在 <代码>multiprocessing.__dict__.在其他情况下,则不是.

These checks have been performed in Python 3.9.1. It is worth noting that, when multiprocessing.queues was already recognized and therefore the checks didn't throw the AttributeError, queues was present in multiprocessing.__dict__. In the other cases, it is not.

这对专家来说似乎很自然,因为 __dict__ 是(AFAIK)属性列表,但我想指出它,因为我说过我不是专家,我不不知道它的实际含义.

This may seem natural to the expert eye, since __dict__ is (AFAIK) a list of attributes, but I wanted to point it out since as I said I'm not an expert and I don't know the actual implications of it.

附注.我已将问题标记为 Python 3.8,因为它已在 3.83.9 中进行了测试,结果相同,以防有差异我想要3.8 的答案.这些差异可能是由于多处理库的变化而出现的,因为文档反映在函数末尾的几个脚注中.

PS. I've tagged the question as Python 3.8 since it has been tested in both 3.8 and 3.9 with same results, and in case there are differences I would like the answer for 3.8. Those differences are likely to appear due to multiprocessing library changes as the docs reflects in several footnotes at the end of the functions.

PS.2.由于 multiprocessing.__dict__ 的输出,我一直将 multiprocessing.queues 称为模块.再说一次,我不是这方面的专家:

PS.2. I've been referring to multiprocessing.queues as a module due to the output of multiprocessing.__dict__. Again I'm not an expert on the matter:

'queues': <module 'multiprocessing.queues' from 'C:\\Program Files\\Python39\\lib\\multiprocessing\\queues.py'>

推荐答案

这是预期行为.如果你想访问一个子模块,你应该导入它:

This is intended behaviour. If you want to access a submodule, you should import it:

import multiprocessing.queues

a = dict()
isinstance(a, multiprocessing.queues.Queue)

导入子模块会将它们作为属性添加到其父模块中——注意 multiprocessing.queues.Queue 如何是 queue 上的 Queue 的嵌套属性查找> queuemultiprocessing 之后.显式导入可确保在访问子模块之前加载它.

Importing submodules adds them as attributes to their parent module – note how multiprocessing.queues.Queue is a nested attribute lookup of Queue on queue after queue on multiprocessing. An explicit import ensures the submodule will be loaded before accessing it.

当使用任何机制(例如 importlib API、importimport-from 语句或内置 __import__()) 一个绑定被放置在父模块的命名空间中到子模块对象.比如包spam有一个子模块foo,导入spam.foo后,spam就会有一个属性foo 绑定到子模块.

The import system: 5.4.2. Submodules

When a submodule is loaded using any mechanism (e.g. importlib APIs, the import or import-from statements, or built-in __import__()) a binding is placed in the parent module’s namespace to the submodule object. For example, if package spam has a submodule foo, after importing spam.foo, spam will have an attribute foo which is bound to the submodule.

这意味着当另一个操作作为副作用导入子模块时,可以避免跳过显式导出.与所有副作用一样,人们必须实际执行触发动作才能依赖副作用.

This means one can get away skipping an explicit export when another action imports the submodule as a side effect. As with all side effects, one has to actually perform the triggering action in order to rely on the side effect.

由于导入是幂等的(重复导入不会产生不良影响),因此应该导入任何希望访问的模块,而不是依赖其他代码的副作用.

Since imports are idempotent (repeating them has no ill effect), one should import any module one expects to access instead of relying on side effects of other code.

这篇关于在实例化队列之前缺少 multiprocessing.queue 模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆