`from ... import` vs`import .`

wch*_*gin 230 python syntax import module python-import

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

from urllib import request
Run Code Online (Sandbox Code Playgroud)

和片段

import urllib.request
Run Code Online (Sandbox Code Playgroud)

或者它们是否可以互换.如果它们是可互换的,那就是"标准"/"首选"语法(如果有的话)?

谢谢!

g.d*_*d.c 206

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

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

import urllib.request
# used as urllib.request
mine = urllib.request()
Run Code Online (Sandbox Code Playgroud)

为简单起见,您还可以在导入时自己为别名设置别名,或者避免屏蔽内置插件:

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

  • @gddc:PEP 8(两次)明确指定"单尾跟下划线"约定.如果Eclipse产生关于正确代码的烦人警告,那么我们有一个糟糕的IDE,而不是坏习惯. (7认同)
  • 您应该使用尾随下划线(而不是前导)来防止与内置函数发生冲突. (4认同)
  • 我刚尝试导入urllib.request,它根本不起作用(python 2.6.5 Ubuntu). (2认同)

Jam*_*pam 155

很多人已经解释过importvs from,所以我想尝试更多地解释一下,实际的差异在于.

首先,让我准确解释一下基本的import语句.

import X

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

from X import *

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

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

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

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

>>> import sys
>>> import os.path
Run Code Online (Sandbox Code Playgroud)

检查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'>
Run Code Online (Sandbox Code Playgroud)

检查globals()locals()命名空间dict的名称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'
>>>    
Run Code Online (Sandbox Code Playgroud)

从上面的例子中,我们发现只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'>
 >>>
Run Code Online (Sandbox Code Playgroud)

......但不是path:

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

删除osfrom locals()命名空间后,您将无法访问os或者os.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
>>>
Run Code Online (Sandbox Code Playgroud)

现在让我们来看看from.

from

>>> import sys
>>> from os import path
Run Code Online (Sandbox Code Playgroud)

检查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'>
Run Code Online (Sandbox Code Playgroud)

所以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'
>>>
Run Code Online (Sandbox Code Playgroud)

您可以使用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
>>>
Run Code Online (Sandbox Code Playgroud)

让我们从locals()中删除'path':

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

使用别名的最后一个示例:

>>> 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'>
>>>
Run Code Online (Sandbox Code Playgroud)

并没有定义路径:

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

关于使用的一个陷阱 from

name从两个不同的模块导入时:

>>> import sys
>>> from os import stat
>>> locals()['stat']
<built-in function stat>
>>>
>>> stat
<built-in function stat>
Run Code Online (Sandbox Code Playgroud)

shutil再次导入stat :

>>>
>>> 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'>
>>>
Run Code Online (Sandbox Code Playgroud)

最后的进口将赢得胜利

  • 点表示它是相对导入,1 表示当前目录,2 表示父目录,依此类推。 (7认同)
  • 确实如此,但对我而言,所有这些命名空间等都有点令人困惑.所以我更喜欢使用import x然后使用x.what_is_necessary.在我的拙见中,我认为更容易理解并且更容易避免混淆,并且通过这种方式你肯定会避免名称冲突模糊和所有那些东西......对吗? (3认同)
  • `from 是什么意思?import &lt;classyouwant&gt;' 是什么意思?不确定这个点指的是什么。 (3认同)
  • 我喜欢这个答案,因为它教导了如何捕捉鱼而不是提供鱼。 (2认同)

Ana*_*ari 18

它们是有区别的.在某些情况下,其中一个将起作用,另一个则不起作用.这是一个例子:说我们有以下结构:

foo.py
mylib\
    a.py
    b.py
Run Code Online (Sandbox Code Playgroud)

现在,我想导入b.pya.py.我想导入a.pyfoo.我该怎么做呢?a我写的两个陈述:

import b
Run Code Online (Sandbox Code Playgroud)

foo.py我写:

import mylib.a
Run Code Online (Sandbox Code Playgroud)

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

from mylib import b
Run Code Online (Sandbox Code Playgroud)

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