[英]Python site-package imports submodule from script root directory
I used to have this litte script main.py
in a directory eden/
(stripped down to MVE, of course):我曾经将这个小脚本main.py
放在目录eden/
(当然,已精简为 MVE):
#!/usr/bin/env python3
# main.py
import pymongo
uri = "***"
mongo_client = pymongo.MongoClient(uri)
With a venv virtual environment (homebrew Python 3.9.6, pip 21.3.1, pymongo 3.12.1) it ran like a (py)charm.使用 venv 虚拟环境(自制 Python 3.9.6、pip 21.3.1、pymongo 3.12.1),它运行起来就像一个 (py)charm。 eden/
is first in the sys.path
, else only Python standard lib and the site-packages
from the venv
, which just has pymongo
in the requirements.txt
. eden/
是首先在sys.path
,否则只Python的标准库和site-packages
从venv
,这只是有pymongo
在requirements.txt
。
But now I have placed a little subdirectory next to main.py
like so for some completely other reason:但是现在我已经在main.py
旁边放置了一个main.py
目录,因为一些完全其他的原因:
eden/
+- monotonic/
| +- monotonic.py
+- main.py
No __init__.py
files anywhere.任何地方都没有__init__.py
文件。
With this in place main.py
fails like so:有了这个, main.py
像这样失败:
Traceback (most recent call last):
...
File "****/venv/lib/python3.9/site-packages/pymongo/server_description.py", line 72, in __init__
self._last_update_time = _time()
TypeError: 'module' object is not callable
_time
comes into pymongo/server_description.py
like so: _time
像这样进入pymongo/server_description.py
:
# pymongo/server_description.py
from pymongo.monotonic import time as _time
The PyCharm debugger reveals that _time
is PyCharm 调试器显示_time
是
<module 'monotonic.monotonic' from '****/eden/monotonic/monotonic.py'>
so the fix is easy (rename monotonic/
subdirectory), but I completely fail to understand what caused this import:所以修复很容易(重命名monotonic/
子目录),但我完全不明白是什么导致了这个导入:
How can "my" monotonic/monotonic.py
match a from pymongo.monotonic
at all? “我的” monotonic/monotonic.py
如何完全匹配from pymongo.monotonic
a?
"My" monotonic/monotonic.py
does not even offer time
for import (in fact, it's an empty file in the MVE). “我的” monotonic/monotonic.py
甚至没有提供导入time
(实际上,它是 MVE 中的一个空文件)。 So why won't the import in pymongo/server_description.py
fail in the first place?那么为什么pymongo/server_description.py
的导入首先不会失败?
Now Python does not import time as _time
from "my" monotonic/monotonic.py
but the whole module ends up as _time
.现在 Python 不会从“我的” monotonic/monotonic.py
import time as _time
,但整个模块最终为_time
。 I cannot even state a proper question here so confused am I.我什至不能在这里提出一个适当的问题,所以我很困惑。
The bad import will happen only with monotonic/monotonic.py
in place.坏进口会发生只有monotonic/monotonic.py
到位。 When the subdirectory or the .py
file is named differently, like tonic/monotonic.py
or monotonic/tonic.py
, or when monotonic.py
is placed right next to main.py
it will not be used.当子目录或.py
文件的名称不同时,例如tonic/monotonic.py
或monotonic/tonic.py
,或者当monotonic.py
放在main.py
旁边时,它将不会被使用。 What makes <x>/<x>.py
special here?是什么让<x>/<x>.py
在这里特别? Even more so, as no __init.py__
is involved in eden/
.更重要的是,因为eden/
没有__init.py__
。
If you dont put a __init__.py
file then the folder is considered a namespace package.如果您不放置__init__.py
文件,则该文件夹被视为命名空间包。 Thats used to gather different folders in a same package.那用于在同一个包中收集不同的文件夹。 So when python see that, monotonic
is considered a namespace package and its content to be gathered together with any other monotonic folder found in path.因此,当 python 看到这一点时, monotonic
被认为是一个命名空间包,其内容将与路径中找到的任何其他单调文件夹收集在一起。
At any case I dont understand how time is confused with monotonic.无论如何,我不明白时间是如何与单调混淆的。
The solution is to put an empty __init__.py
file解决办法是放一个空的__init__.py
文件
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.