`from ... import` 与 `import .` [重复]

2025-01-16 08:38:00
admin
原创
130
摘要:问题描述:我想知道代码片段之间是否有区别from urllib import request 和片段import urllib.request 或者它们是否可以互换。如果它们可以互换,那么“标准”/“首选”语法是什么(如果有的话)?解决方案 1:这取决于您在引用它时想要如何访问导入。from urllib i...

问题描述:

我想知道代码片段之间是否有区别

from urllib import request

和片段

import urllib.request

或者它们是否可以互换。如果它们可以互换,那么“标准”/“首选”语法是什么(如果有的话)?


解决方案 1:

这取决于您在引用它时想要如何访问导入。

from urllib import request
# access request directly.
mine = request()

import urllib.request
# used as urllib.request
mine = urllib.request()

为了简单起见或避免掩盖内置函数,您还可以在导入时自己设置别名:

from os import open as open_
# lets you use os.open without destroying the 
# built in open() which returns file handles.

解决方案 2:

很多人已经解释过importvs 了from,所以我想尝试更深入地解释一下,看看实际的区别在哪里。

首先,让我详细解释一下基本导入语句的作用。

import X

导入模块X,并在当前命名空间中创建对该模块的引用。然后,您需要定义完整的模块路径,以便从模块内部访问特定属性或方法(例如:
X.nameX.attribute

from X import *

导入模块X,并创建对当前命名空间中该模块定义的所有公共对象的引用(即,所有不以 开头的名称的对象_)或您提到的任何名称。

或者换句话说,运行此语句后,您可以简单地使用普通(非限定)名称来引用 module 中定义的内容X。但X其本身未定义,因此X.name不起作用。如果name
已定义,则将被新版本替换。如果 nameX更改为指向其他对象,您的模块不会注意到。

这使得模块中的所有名称都可以在本地命名空间中使用。

现在让我们看看当我们这样做时会发生什么import X.Y

>>> import sys
>>> import os.path

检查sys.modules姓名osos.path

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

检查名称空间字典globals()locals()加上名称osos.path

 >>> globals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> locals()['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> globals()['os.path']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os.path'
>>>    

从上面的例子中,我们发现只有os添加到本地和全局命名空间中。因此,我们应该能够使用os

 >>> os
 <module 'os' from     
  '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
 >>> os.path
 <module 'posixpath' from      
 '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
 >>>

…但不是path

>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined 
>>>

os一旦从命名空间中删除locals(),您将无法访问osos.path,即使它们确实存在于sys.modules

>>> del locals()['os']
>>> os
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>

现在我们来看看from

from

>>> import sys
>>> from os import path

检查sys.modules姓名osos.path

>>> sys.modules['os']
<module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
>>> sys.modules['os.path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>

因此sys.modules看起来和我们使用导入时一样import name

好的。让我们检查一下它的命名空间字典是什么locals()样子globals()的:

>>> globals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> locals()['path']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['os']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'os'
>>>

您可以通过使用 来访问path,但不能通过 来访问os.path

>>> path
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> os.path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined
>>>
 

让我们从 locals() 中删除“路径”:

>>> del locals()['path']
>>> path
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'path' is not defined
>>>

最后再举一个使用别名的例子:

>>> from os import path as HELL_BOY
>>> locals()['HELL_BOY']
<module 'posixpath' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>> globals()['HELL_BOY']
<module 'posixpath' from /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/posixpath.pyc'>
>>>

并且没有定义路径:

>>> globals()['path']
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
KeyError: 'path'
>>>

使用的一个陷阱from

当您从两个不同的模块导入相同的内容时name

>>> import sys
>>> from os import stat
>>> locals()['stat']
<built-in function stat>
>>>
>>> stat
<built-in function stat>

再次导入统计数据shutil

>>>
>>> from shutil import stat
>>> locals()['stat']
<module 'stat' from 
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/stat.pyc'>
>>> stat
<module 'stat' from 
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/stat.pyc'>
>>>

最后的进口将获胜

解决方案 3:

两者是有区别的。在某些情况下,其中一个会起作用,而另一个则不会。以下是一个例子:假设我们有以下结构:

foo.py
mylib\n    a.py
    b.py

现在,我想导入b.pya.py我想导入a.pyfoo我该怎么做?两个语句,a我在 中写道:

import b

我写道foo.py

import mylib.a

那么,ImportError在尝试运行 时,这将生成一个foo.py。解释器将抱怨a.py( import b) 中的 import 语句,说没有模块 b。那么如何解决这个问题呢?在这种情况下,将 中的 import 语句更改aimport mylib.b
将不起作用,因为ab都在 中mylib。这里的解决方案(或至少一个解决方案)是使用绝对导入:

from mylib import b

来源:Python:导入模块,导入模块

解决方案 4:

您使用的是 Python3 中的 urllib 包。两种形式都可以接受,并且没有哪种导入形式优于另一种。有时,当涉及多个包目录时,您可能使用前者from x.y.z.a import s

在使用 urllib 包的这个特殊情况下,第二种方式import urllib.request和用法urllib.request是标准库如何统一使用它。

解决方案 5:

在 Python 2.x 中至少你不能这样做import urllib2.urlopen

你必须做from urllib2 import urlopen

Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import urllib2.urlopen
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named urlopen
>>> import urllib.request
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named request
>>>

解决方案 6:

我对 import urllib.request 的主要抱怨是即使没有导入 urllib.parse 仍然可以引用它。

>>> import urllib3.request
>>> urllib3.logging
<module 'logging' from '/usr/lib/python2.7/logging/__init__.pyc'>

对我来说请求是在 urllib3 下。Python 2.7.4 ubuntu

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用