我很难理解import语句及其变体。
假设我正在使用lxml
模块来抓取网站。
以下示例显示......
from lxml.html import parse
parse( 'http://somesite' )
... Google的python样式指南更喜欢基本的import语句,以保留名称空间。
我更喜欢这样做,但是当我尝试这个时:
import lxml
lxml.html.parse( 'http://somesite' )
...然后我收到以下错误消息:
AttributeError:'module'对象没有属性'html'
任何人都可以帮我理解发生了什么吗?我更喜欢在命名空间中使用模块,但需要一些帮助来理解语义。
答案 0 :(得分:10)
import lxml.html as LH
doc = LH.parse('http://somesite')
lxml.html
是一个模块。当您import lxml
时,html
模块未导入lxml
命名空间。这是开发人员的决定。有些软件包会自动导入某些模块,有些则不会。在这种情况下,您必须自己使用import lxml.html
。
import lxml.html as LH
导入html
模块并将其绑定到当前模块命名空间中的名称LH
。因此,您可以使用LH.parse
访问解析函数。
如果您想深入研究包(如lxml
)何时自动导入模块(如lxml.html
),请打开终端并输入
In [16]: import lxml
In [17]: lxml
Out[17]: <module 'lxml' from '/usr/lib/python2.7/dist-packages/lxml/__init__.pyc'>
您可以在此处看到lxml
包的__init__.py
文件的路径。
如果你查看你发现的内容是空的。因此不会导入任何子模块。如果您查看numpy的__init__.py
,您会看到许多代码,其中包括
import linalg
import fft
import polynomial
import random
import ctypeslib
import ma
这些都是导入numpy
命名空间的子模块。因此,从用户的角度来看,import numpy
会自动让您访问numpy.linalg
,numpy.fft
等。
答案 1 :(得分:6)
我们来看一个包pkg
的示例,其中包含两个模块a.py
和b.py
:
--pkg
|
| -- a.py
|
| -- b.py
|
| -- __init__.py
在__init__.py
导入a.py
和不 b.py
:
导入
因此,如果您打开终端并执行:
>>> import pkg
>>> pkg.a
>>> pkg.b
AttributeError: 'module' object has no attribute 'b'
正如您所看到的,因为我们已经在pkg a.py
中导入了__init__.py
,因此我们可以将其作为pkg
的属性进行访问,但b
不存在,所以稍后我们应该使用:
>>> import pkg.b # OR: from pkg import b
HTH,
答案 2 :(得分:3)
当你import
一个包时,解释器在pythonpath上查找包,然后如果找到,解析并运行包__init__.py
,从中构建包对象,并插入该对象到sys.modules
。当importing
一个模块时,它会做同样的事情,除了它创建并添加一个模块对象。当您随后尝试访问属性(也称为成员方法,类,子模块或子包)时,它将从sys.modules
检索相应的对象,并在子模块或包对象上尝试getattr
你要。但是,如果子项是尚未imported
的子模块或子包,则它尚未添加到sys.modules
或模块或包的属性列表中,因此您将获得AttributeError
。因此,您必须在代码中显式导入模块或包,或者在包__init__.py
中委派它,以便在运行时在其父级上可用。