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

2025-01-16 08:38:00
admin
原创
11
摘要:问题描述:我想知道代码片段之间是否有区别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

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1041  
  IPD(Integrated Product Development,集成产品开发)是一种系统化的产品开发方法论,旨在通过跨职能团队的协作,优化产品开发的效率和质量。IPD流程强调从市场需求出发,通过并行工程、跨部门协作和阶段性评审,确保产品从概念到上市的每个环节都高效且可控。随着敏捷开发方法的普及,越来越多的企业开始...
华为IPD流程   34  
  随着企业产品开发复杂度的提升以及市场需求的快速变化,传统的产品开发模式逐渐显现出局限性。集成产品开发(IPD)流程与敏捷开发(Agile Development)作为两种主流的开发方法论,分别从系统化管理和快速响应需求的角度为企业提供了解决方案。然而,单独使用其中一种方法往往无法完全满足企业在效率、质量和创新上的多重需...
华为IPD流程   31  
  华为IPD(Integrated Product Development,集成产品开发)流程是华为公司成功的关键因素之一。它不仅帮助华为在技术上实现了快速创新,还通过市场导向确保了产品的商业成功。IPD流程通过整合技术与市场双驱动,实现了从需求定义到产品交付的全生命周期管理。这种模式不仅提高了产品的开发效率,还降低了市...
IPD流程中PDCP是什么意思   23  
  在研发领域,集成产品开发(IPD)流程已经成为企业提升创新效率和市场竞争力的重要手段。然而,资源分配的不合理往往是制约IPD流程效率的关键因素之一。无论是人力资源、财务资源还是技术资源,如何高效分配直接关系到项目的成功与否。优化资源分配不仅能够缩短产品开发周期,还能降低研发成本,提升产品的市场竞争力。因此,掌握资源分配...
IPD流程中CDCP   26  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用