python包的导入
‘壹’ python包相对导入的陷阱是
包相对导入的陷阱:混合使用,相比于Python 2.X的隐式包相对导入,以及Python 2.X和3.X中的显式包相对导入点号语法,有些时候从 sys.path上一个路径出发的绝对包导入会是更推荐的选择。这一问题可能看上去难以理解,但是当你开始编写自己的包,可能就会变得更加重要了。 如前所述,Python 3.X的相对导入语法和默认绝对导入搜索规则,让包内导入变得显式从而使其更容易被注意和被维护,而且允许你在一些命名冲突的情况下显式地进行选择。然而,你也必须注意到该模型带来的下面两个结果:在Python 3.X和2.X中,包相对导入语句的使用会隐式地将一个文件与一个包目录的角色进行绑定,并禁止该文件通过其他方式被使用。在Python 3.X中,新的相对导入搜索规则改变意味着一个文件不能像在2.X中那样同时扮演脚本和包模块的角色。这些约束的理由有些微妙,不过由于下面的两条同时成立:Python 3.X和2.X不允许随意使用from .的相对导入语法,除非发起导入的文件本身作为包的一部分(即该文件在其他地方被导入)。Python 3.X的导入不会搜索一个包模块自身的路径,除非使用了from .的相对导入语法(或该模块位于当前工作路径、顶层脚本的主目录下)。使用相对导入会阻止你在2.X和3.X中创建同时扮演可执行程序和外部可导入包角色的目录项。此外,一些文件在3.X中不能像在2.X中那样同时扮演脚本和包模块的角色。就导人语句来说,这些规则可以归结为下面的两行代码的形式:前一行在Python 2.X和3.X中都只用于包模式,而后一行在3.X中只用于程序模式。
最终的效果是不论2.X还是3.X中的文件,你都应该只选择一种使用模式,即包模式(使用相对导入)或程序模式(使用简单导入),并将真正的包模块文件单独放到一个子目录中,与顶层脚本文件隔离开来。
另一方面,你可以尝试手动改变sys.path(通常是一项脆弱并易出错的任务)或总是通过绝对导入使用完整的包路径,并且假定包的根目录位于模块搜索路径上,来替代包相对导入语法或简单导入。
‘贰’ python2包的导入问题
可以试试在core和config文件夹的同级再加上__init__.py(为了表名这文件夹也是一个模块)
‘叁’ python命名空间包导入算法
要理解命名空间包,需从底层去学习包导入操作在Python 3.3中是如何完成的。在导入过程中,3.3版本与3.2和之前的版本一样,依旧会遍历模块搜索路径sys.path中的每个目录。然而,在3.3版本中,当对每个模块搜索路径中的directory搜索名为spam的被导人包时,Python会按照下面的顺序测试一系列更广的匹配条件:
1.如果找到directory\spaml_init__.py,便会导入一个常规包并返回。
2.如果找到directoryspam.ipy,pyc,或其他模块扩展名},便会导人一个简单模块并
返回。
3.如果找到文件夹directorylspam,便会将其记录下来,而扫描将从搜索路径中的下一
个目录继续。
4.如果上述的所有都没有找到,扫描将从搜索路径中的下一个目录继续。
如果搜索路径扫描结束后没有从上述步骤1和步骤2中返回一个模块或包,而同时在上述步骤3中至少记录了一个路径,那么就会创建一个命名空间包。
命名空间包的创建会立即发生,而且不会推迟到一个子层级的导入发生之时。新的命名空间包有一个_path_属性,该属性被设置为在上述步骤3中扫描并记录的目录路径字符串的可迭代对象,但是没有_file_属性。
path_属性在随后更深的访问过程中用于搜索所有包组件。命名空间包的_path_中每个被记录的项目,都会在进一步嵌套的项目被请求时进行搜索,这很像一个常规包的单独路径。
从另一方面看,命名空间包的_path_属性对于更低层次组件的关系,和sys.path对于顶层最左侧的包导入路径的关系是一样的。命名空间包成为了访问更低层次项目的“父路径”,这一访问也使用了上面介绍的四个步骤。
最终的结果是一个命名空间包是一种对多个目录的虚拟拼接,这些目录可以位于多个sys.path项目中。然而一旦一个命名空间包被创建,它和一个常规包之间并没有功能上的区别,它能够支持我们所学过的常规包的一切功能,包括包相对导入语法。
‘肆’ Python怎么导入文件
Python的import包含文件功能就跟PHP的include类似,但更确切的说应该更像是PHP中的require,因为Python里的import只要目标不存在就报错程序无法往下执行。要包含目录里的文件,PHP中只需要给对路径就OK。Python中则不同,下面来看看这个例子。
目录结构:
重新执行a.py,一切OK!
‘伍’ python怎样导入自己写的包
python导入自己写的包的方法:
1、导入同级目录下的文件可以用“import 包名”导入
2、导入子目录文件可以用“from 包名 import 文件名”导入
更多Python知识,请关注:Python自学网!!
‘陆’ 如何把一个python包导入到python库中
Python 运行环境在查找模块时是对 sys.path 列表进行遍历,如果我们想在运行环境中添加自定义的模块,主要有以下三种方法:
1. 在sys.path列表中添加新的路径(只能对执行了 sys.path.append 命令的当前 Python 运行环境起作用,对其他运行环境不起作用,也即“一次性”的)。
>>> import sys
>>> sys.path
>>> sys.path.append('/home/xxx/yyy') #目录/home/xxx/yyy包含你所需要的包或模块
设置 PYTHONPATH 环境变量(永久性添加):
2. 将包或模块复制到 sys.path 列表中的目录(通过 sys.path 查看)里(如 /home/test/lib/python2.7/site-packages/ 目录)。
3. 最简单的办法是用 .pth 文件来实现。Python 在遍历已有的库文件目录(sys.path中指定)过程中,如果见到一个 .pth 文件,就会将该文件中所记录的路径加入到 sys.path 设置中,这样 .pth 文件说指明的库也就可以被 Python 运行环境找到。
$cd /home/test/lib/python2.7/site-packages/
$touch test.pth
$vim test.pth
$添加一行包或模块所在的目录(如:/home/test/somePackage/)
则test.pth文件内容为:
/home/test/somePackage/
‘柒’ python怎么导入自己写的包
包(packages)其实也是模块,其类型Type也是mole。通常引用自定义模块时有两种方法:
1)将两个文件放在同一目录下。
2)在sys.path下添加要引用的py文件的路径。然后import。
这样的做法,对于少数文件是可行的,但如果程序数目很多,层级很复杂时就比较麻烦了。此时用package就能将多个py文件组织起来,类似于第三方包一样的引用。要方便很多。
package的层次结构与程序所在目录的层次结构相同,且必须包含一个__init__.py的文件。__init__.py可以为空,只要它存在就表明此目录被作为一个package处理。
package1/
__init__.py
subPack1/
__init__.py
mole_11.py
mole_12.py
mole_13.py
subPack2/
__init__.py
mole_21.py
mole_22.py
……
__init__.py可以为空,只要它存在,就表明此目录应被作为一个package处理。当然,__init__.py中也可以设置相应的内容。
好了,现在我们在mole_11.py中定义一个函数:
def funA():
print "funcA in mole_11"
return
一.引用模块
在顶层目录(也就是package1所在的目录,当然也参考上面的介绍,将package1放在解释器能够搜索到的地方)运行python:
>>>from package1.subPack1.mole_11 import funcA
>>>funcA()
funcA in mole_11
这样,我们就按照package的层次关系,正确调用了mole_11中的函数。
二.使用通配符*,导入某个mole中的所有元素
答案就在__init__.py中。我们在subPack1的__init__.py文件中写
__all__ = ['mole_13', 'mole_12']
然后进入python
>>>from package1.subPack1 import *
>>>mole_11.funcA()
Traceback (most recent call last):
File "", line 1, in
ImportError: No mole named mole_11
也就是说,以*导入时,package内的mole是受__init__.py限制的。
三.在package内部互相调用。
1.如果希望调用同一个package中的mole,则直接import即可。也就是说,在mole_12.py中,可以直接使用
import mole_11
2.如果不在同一个package中,例如我们希望在mole_21.py中调用mole_11.py中的FuncA,则应该这样:
from mole_11包名.mole_11 import funcA
四.Python如何找到我们定义的mole?
在标准包sys中path属性记录了Python的包路径。
import sys
print(sys.path)
通常我们可以将mole的包路径放到环境变量PYTHONPATH中,该环境变量会自动添加到sys.path属性.
另一种方便的方法是编程中直接指定我们的mole路径到sys.path 中。
常用的话也可以放在python27\lib\site-packages文件夹下。
‘捌’ python 中库怎么导入
让包内导入更加显式,这个功能的一部分设计初衷是,为了帮助脚本解决同名文件出现在模块搜索路径上多个不同位置时的二义性。考虑包目录,这定义了一个名为mypkg 的包,其中含有名为mypkg.main和mypkg.string 的模块。现在,假设模块main试图导入名为string的模块。在 Python 2.X和更早版本中,Python会先寻找mypkg目录以执行相对导入。这会找到并导入位于该处的string.py文件,将其赋值给mypkg.main模块命名空间内的名称string。不过,这一导入的本意可能是要导入Python标准库的string模块。可惜的是,在这些Python版本中,无法直接忽略mypkg.string 去寻找位于模块搜索路径更右侧的标准库中的string模块。此外,我们无法使用完整包导入路径来解决这个问题,因为我们无法依赖在每台机器上的标准链接库路径。换句话说,包中的简单导入可能具有二义性而且容易出错。在包内,我们无法确定imports pam语句指的是包内的模块还是包外的模块。一种可能的后果是,一个局部的模块或包会在不经意间隐藏了sys.path 上的另一个模块。
在实践中,Python使用者可以避免为他们自己的模块重复使用标准库模块的名称(如果需要标准string库,就不要把新的模块命名为string)。但是,一个包还是有可能意外地隐藏标准库模块。再者,Python 以后可能新增标准库模块,而其名称可能刚好就和自己的一个模块同名。而依赖于没有点号开头相对导入的程序代码同样也不容易理解,因为读者可能对希望使用哪个模块而感到困惑。所以我们最好能在代码中显式地指出导入的解析过程。
‘玖’ 如何导入python中的模块
定义模块,只要使用文本编辑器,把一些python代码输入到文本中,然后以.py为后缀名进行保存,任何此类文件都会被认为是python模块。
比如说,下面的代码输入到一个文件中,就可以看作是一个模块:
def
printme(var):
print
varif
__name__
==
'__main__':
printme(1)
假设说输入到a.py中,那么import
a就可以把这个模块导入。
然后可执行a.printme(3),屏幕即可打印出3:
>>>
a.printme(3)3>>>
一个模块顶层定义的变量,会自动变成模块的属性。例如:
data=[1,2,3]def
printme(var):
print
varif
__name__
==
'__main__':
printme(1)
data变量就是模块的一个属性。其实printme也是一个属性,只不过是一个函数罢了。
引入模块示例如下:(假定此时data=[1,2,3]未定义)
>>>
import
a>>>
a.data
Traceback
(most
recent
call
last):
File
"<pyshell#1>",
line
1,
in
<mole>
a.dataAttributeError:
'mole'
object
has
no
attribute
'data'>>>
reload(a)<mole
'a'
from
'C:/py\a.pyc'>>>>
a.data
Traceback
(most
recent
call
last):
File
"<pyshell#3>",
line
1,
in
<mole>
a.dataAttributeError:
'mole'
object
has
no
attribute
'data'>>>
从上述提示可以看出data属性未定义,此时再在a.py文件中定义data=[1,2,3],重新加载a模块,并输出data属性:
>>>
reload(a)<mole
'a'
from
'C:/py\a.py'>>>>
a.data[1,
2,
3]>>>
这里的reload函数可以重新加载一个模块。如果在模块代码中更改了,那么需要重新加载。
上面a.data,就是访问模块中的属性。
上面的例子是导入一个文件作为一个模块。
其实python的模块导入还有更丰富的内容。
除了模块名之外,python也可以导入指定目录路径。python代码的目录就称为包。因此,这类导入就称为包导入。事实上,包导入是把计算机上的目录变成python的一个命名空间。而属性就是目录中包含的子目录或者是模块文件。
看下面例子:
在我的桌面上有一个aa文件夹,里面有bb文件夹,bb里面有a.py这个文件。
那么在aa和bb文件夹中分别放置一个__init__.py,之后,在命令行中import
aa.bb.a,就可以导入模块a了。
‘拾’ python 类和继承,包及模块导入 求解答
一 .mole
通常模块为一个文件,直接使用import来导入就好了。可以作为mole的文件类型有".py"、".pyo"、".pyc"、".pyd"、".so"、".dll"。
二. package
通常包总是一个目录,可以使用import导入包,或者from + import来导入包中的部分模块。包目录下为首的一个文件便是 __init__.py。然后是一些模块文件和子目录,假如子目录中也有 __init__.py 那么它就是这个包的子包了。
一.模块你可以使用import语句将一个源代码文件作为模块导入.例如:
[python]view plain
#file:spam.py
a=37#一个变量
deffoo:#一个函数
print"I'mfoo"
classbar:#一个类
defgrok(self):
print"I'mbar.grok"
b=bar()#创建一个实例
- 1.为源代码文件中定义的对象创建一个名字空间,通过这个名字空间可以访问到模块中定义的函数及变量。
- 2.在新创建的名字空间里执行源代码文件.
- 3.创建一个名为源代码文件的对象,该对象引用模块的名字空间,这样就可以通过这个对象访问模块中的函数及变量,如:
importspam#导入并运行模块spam
printspam.a#访问模块spam的属性
spam.foo()
c=spam.bar()
importsocket,os,regex
- 模块导入时可以使用 as 关键字来改变模块的引用对象名字:
importosassystem
importsocketasnet,threadasthreads
system.chdir("..")
net.gethostname()
- 使用from语句可以将模块中的对象直接导入到当前的名字空间. from语句不创建一个到模块名字空间的引用对象,而是把被导入模块的一个或多个对象直接放入当前的名字空间:
fromsocketimportgethostname#将gethostname放如当前名字空间
printgethostname()#直接调用
socket.gethostname()#引发异常NameError:socket
fromsocketimportgethostname,socket
fromsocketimport*#载入所有对象到当前名字空间
- 不过,如果一个模块如果定义有列表__all__,则from mole import * 语句只能导入__all__列表中存在的对象。
#mole:foo.py
__all__=['bar','spam']#定义使用`*`可以导入的对象
h=hostname()
- from mole import * 语句只能用于一个模块的最顶层.*特别注意*:由于存在作用域冲突,不允许在函数中使用from 语句。
- 每个模块都拥有 __name__ 属性,它是一个内容为模块名字的字符串。最顶层的模块名称是 __main__ .命令行或是交互模式下程序都运行在__main__ 模块内部. 利用__name__属性,我们可以让同一个程序在不同的场合(单独执行或被导入)具有不同的行为,象下面这样做:
#检查是单独执行还是被导入
if__name__=='__main__':
#Yes
statements
else:
#No(可能被作为模块导入)
statements
- 模块搜索路径
- 导入模块时,解释器会搜索sys.path列表,这个列表中保存着一系列目录。一个典型的sys.path 列表的值:
- Linux:
- ['', '/usr/local/lib/python2.0',
- '/usr/local/lib/python2.0/plat-sunos5',
- '/usr/local/lib/python2.0/lib-tk',
- '/usr/local/lib/python2.0/lib-dynload',
- '/usr/local/lib/python2.0/site-packages']
- Windows:
- ['', 'C:\WINDOWS\system32\python24.zip', 'C:\Documents and Settings\weizhong', 'C:\Python24\DLLs', 'C:\Python24\lib', 'C:\Python24\lib\plat-win', 'C:\Python24\lib\lib-tk', 'C:\Python24\Lib\site-packages\pythonwin', 'C:\Python24', 'C:\Python24\lib\site-packages', 'C:\Python24\lib\site-packages\win32', 'C:\Python24\lib\site-packages\win32\lib', 'C:\Python24\lib\site-packages\wx-2.6-msw-unicode']
- 空字符串 代表当前目录. 要加入新的搜索路径,只需要将这个路径加入到这个列表.
- 模块导入和汇编
- 到现在为止,本章介绍的模块都是包含Python源代码的文本文件. 不过模块不限于此,可以被 import 语句导入的模块共有以下四类:
- •使用Python写的程序( .py文件)
- •C或C++扩展(已编译为共享库或DLL文件)
- •包(包含多个模块)
- •内建模块(使用C编写并已链接到Python解释器内)
- 当查询模块 foo 时,解释器按照 sys.path 列表中目录顺序来查找以下文件(目录也是文件的一种):
- 1.定义为一个包的目录 foo
- 2.foo.so, foomole.so, foomole.sl,或 foomole.dll (已编译扩展)
- 3.foo.pyo (只在使用 -O 或 -OO 选项时)
- 4.foo.pyc
- 5.foo.py
- 对于.py文件,当一个模块第一次被导入时,它就被汇编为字节代码,并将字节码写入一个同名的 .pyc文件.后来的导入操作会直接读取.pyc文件而不是.py文件.(除非.py文件的修改日期更新,这种情况会重新生成.pyc文件) 在解释器使用 -O 选项时,扩展名为.pyo的同名文件被使用. pyo文件的内容虽去掉行号,断言,及其他调试信息的字节码,体积更小,运行速度更快.如果使用-OO选项代替-O,则文档字符串也会在创建.pyo文件时也被忽略.
- 如果在sys.path提供的所有路径均查找失败,解释器会继续在内建模块中寻找,如果再次失败,则引发 ImportError 异常.
- .pyc和.pyo文件的汇编,当且仅当import 语句执行时进行.
- 当 import 语句搜索文件时,文件名是大小写敏感的。即使在文件系统大小写不敏感的系统上也是如此(Windows等). 这样, import foo 只会导入文件foo.py而不会是FOO.PY.
- 重新导入模块
- 如果更新了一个已经用import语句导入的模块,内建函数reload()可以重新导入并运行更新后的模块代码.它需要一个模块对象做为参数.例如:
- import foo
- ... some code ...
- reload(foo) # 重新导入 foo
- 在reload()运行之后的针对模块的操作都会使用新导入代码,不过reload()并不会更新使用旧模块创建的对象,因此有可能出现新旧版本对象共存的情况。 *注意* 使用C或C++编译的模块不能通过 reload() 函数来重新导入。记住一个原则,除非是在调试和开发过程中,否则不要使用reload()函数.
使用import spam 语句就可以将这个文件作为模块导入。系统在导入模块时,要做以下三件事:
[python]view plain
用逗号分割模块名称就可以同时导入多个模块:
[python]view plain
[python]view plain
[python]view plain
from语句支持逗号分割的对象,也可以使用星号(*)代表模块中除下划线开头的所有对象:
[python]view plain
[python]view plain
另外, as 也可以和 from 联合使用:
[python]view plain
import 语句可以在程序的任何位置使用,你可以在程序中多次导入同一个模块,但模块中的代码*仅仅*在该模块被首次导入时执行。后面的import语句只是简单的创建一个到模块名字空间的引用而已。sys.moles字典中保存着所有被导入模块的模块名到模块对象的映射。这个字典用来决定是否需要使用import语句来导入一个模块的最新拷贝.
[python]view plain