Python 和 iPython 子模块导入差异

Python and iPython submodule import differences

我最近将使用 pytz 的解决方案迁移到了 dateutil.tz。我已经用 iPython 测试了所有内容,并且效果很好。但是,在生产中 python... ERROR!

谁能解释为什么 Python 和 iPython 对导入的处理方式不同,如果有办法让 python 的行为与 iPython 的行为相同?

$ python3
Python 3.8.5 (default, Jul 21 2020, 10:48:26) 
Type "help", "copyright", "credits" or "license" for more information.
>>> import dateutil
>>> dateutil.__file__
'/usr/local/lib/python3.8/site-packages/dateutil/__init__.py'
>>> dateutil.tz
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'dateutil' has no attribute 'tz'
>>> 
$ ipython
Python 3.8.5 (default, Jul 21 2020, 10:48:26) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.19.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import dateutil

In [2]: dateutil.__file__
Out[2]: '/usr/local/lib/python3.8/site-packages/dateutil/__init__.py'

In [3]: dateutil.tz
Out[3]: <module 'dateutil.tz' from '/usr/local/lib/python3.8/site-packages/dateutil/tz/__init__.py'>

因为IPython想太聪明了。由于任何原因,它已经导入 dateutil.tz 并且当您手动导入 dateutil 时,然后 dateutil.tz 在您的主命名空间中可用。

但是因为它是一个子模块,所以如果你想使用它,你应该始终导入它。因此,您应该将 import dateutil 替换为 import dateutil.tz,您的代码将在两种环境下正常工作。

$ python3
Python 3.8.5 (default, Jul 21 2020, 10:48:26) 
Type "help", "copyright", "credits" or "license" for more information.
>>> import dateutil.tz
>>> dateutil.__file__
'/usr/local/lib/python3.8/site-packages/dateutil/__init__.py'
>>> dateutil.tz
<module 'dateutil.tz' from '/usr/local/lib/python3.8/site-packages/dateutil/tz/__init__.py'>