加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

Python从命令行运行时,import urllib.parse失败

发布时间:2020-12-16 23:46:15 所属栏目:Python 来源:网络整理
导读:我在python 3.4.2中观察到以下行为,我无法解释它.希望有人可以解释一下这个问题: 在IPython中: In [129]: import urllibIn [130]: print(urllib.parse) 我导入了一个模块,并打印了其中一个属性.一切都按预期工作.到目前为止,生活是美好的. 现在,我从命令行

我在python 3.4.2中观察到以下行为,我无法解释它.希望有人可以解释一下这个问题:

在IPython中:

In [129]: import urllib

In [130]: print(urllib.parse)

我导入了一个模块,并打印了其中一个属性.一切都按预期工作.到目前为止,生活是美好的.

现在,我从命令行做同样的事情:

$python -c 'import urllib; print(urllib.parse)'  
Traceback (most recent call last):
  File "

说什么?!这不是应该如何工作的.
好吧,也许这是一个Python般的行为;使用-c标志时,可能不会立即导入模块.我们来试试另一个模块:

$python -c 'import datetime; print(datetime.datetime)'

什么?!它如何适用于datetime而不是urllib?我在两个地方都使用相同版本的python(3.4.2)

有没有人对此有任何想法?

编辑:

根据其中一条评论:

$which -a ipython
/Users/ashwin/.pyenv/shims/ipython
/Library/Frameworks/Python.framework/Versions/2.7/bin/ipython
/usr/local/bin/ipython
/usr/local/bin/ipython

$which -a python
/Users/ashwin/.pyenv/shims/python
/Library/Frameworks/Python.framework/Versions/2.7/bin/python
/usr/bin/python
/usr/bin/python
最佳答案
当您运行import urllib时,它会创建urllib模块的模块对象(实际上是package)而不导入其子模块(解析,请求等).

如果要使用属性访问权限访问其子模块,则需要父模块对象(urllib)位于命名空间中.除此之外,必须已经加载(导入)该子模块.从documentation开始:

if package spam has a submodule foo,after importing
spam.foo,spam will have an attribute foo which is bound to the
submodule. […] The invariant holding is that if you have
sys.modules['spam'] and sys.modules['spam.foo'] (as you would
after the above import),the latter must appear as the foo attribute
of the former.

每个模块只有一个实例,因此对urllib模块对象(存储在sys.modules [‘urllib’]中)所做的任何更改都会反映在任何地方.

你不要导入urllib.parse,但是IPython会这样做.为了证明这一点,我将创建一个启动文件:

import urllib
print('Running the startup file: ',end='')
try:
    # After importing  'urllib.parse' ANYWHERE,# 'urllib' will have the 'parse' attribute.
    # You could also do "import sys; sys.modules['urllib'].parse"
    urllib.parse
except AttributeError:
    print("urllib.parse hasn't been imported yet")
else:
    print('urllib.parse has already been imported')
print('Exiting the startup file.')

并启动ipython

vaultah@base:~$ipython
Running urllib/parse.py
Running the startup file: urllib.parse has already been imported
Exiting the startup file.
Python 3.6.0a0 (default:089146b8ccc6,Sep 25 2015,14:16:56) 
Type "copyright","credits" or "license" for more information.

IPython 4.0.0 -- An enhanced Interactive Python.

这是在IPython启动期间导入pydoc的副作用(ipython是/usr/local/bin / ipython):

/usr/local/bin/ipython,line 7:
  from IPython import start_ipython
/usr/local/lib/python3.6/site-packages/IPython/__init__.py,line 47:
  from .core.application import Application
/usr/local/lib/python3.6/site-packages/IPython/core/application.py,line 24:
  from IPython.core import release,crashhandler
/usr/local/lib/python3.6/site-packages/IPython/core/crashhandler.py,line 28:
  from IPython.core import ultratb
/usr/local/lib/python3.6/site-packages/IPython/core/ultratb.py,line 90:
  import pydoc
/usr/local/lib/python3.6/pydoc.py,line 68:
  import urllib.parse

这解释了为什么下面的代码失败 – 你只导入urllib,似乎没有任何东西导入urllib.parse:

$python -c 'import urllib; print(urllib.parse)'

另一方面,以下命令有效,因为datetime.datetime不是模块.它是在导入日期时导入的类.

$python -c 'import datetime; print(datetime.datetime)'

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读