Python3.5入门学习记录-模块

模块让你可以有逻辑地组织你的Python代码段。函数

把相关的代码分配到一个 模块里能让你的代码更好用,更易懂。spa

模块也是Python对象,具备随机的名字属性用来绑定或引用。设计

简单地说,模块就是一个保存了Python代码的文件。模块能定义函数,类和变量。模块里也能包含可执行的代码。3d

例子code

一个叫作aname的模块里的Python代码通常都能在一个叫aname.py的文件中找到。下例是个简单的模块common.py。orm

def printFunc(param):
    print(("Hello:{0}".format(param)))
    return

import 语句对象

想使用Python源文件,只需在另外一个源文件里执行import语句,语法以下:blog

import module1[, module2[,... moduleN]

当解释器遇到import语句,若是模块在当前的搜索路径就会被导入。索引

搜索路径是一个解释器会先进行搜索的全部目录的列表。如想要导入模块common.py,须要把命令放在脚本的顶端:ci

#导入模块
import Common

#调用模块里的函数
Common.printFunc("name")

From…import语句

Python的from语句让你从模块中导入一个指定的部分到当前命名空间中。语法以下:

from modname import name1[, name2[, ... nameN]]

例如,要导入模块fib的fibonacci函数,使用以下语句:

from fib import fibonacci
实例:
咱们在Common.py中在添加一个方法
def printFunc(param):
    print(("Hello:{0}".format(param)))
    return

def printFunc1(param):
    print(("Hello1:{0}".format(param)))
    return

而后引入printFunc1

from Common import printFunc1

printFunc1("printFunc1")

你们发现了么?from…import引入的函数,不须要使用模块名称就能够直接调用

From…import* 语句

把一个模块的全部内容全都导入到当前的命名空间也是可行的,只需使用以下声明:

from modname import *

这提供了一个简单的方法来导入一个模块中的全部项目

命名空间和做用域

一个Python表达式能够访问局部命名空间和全局命名空间里的变量。若是一个局部变量和一个全局变量重名,则局部变量会覆盖全局变量。

每一个函数都有本身的命名空间。类的方法的做用域规则和一般函数的同样。

Python会智能地猜想一个变量是局部的仍是全局的,它假设任何在函数内赋值的变量都是局部的。

所以,若是要给全局变量在一个函数里赋值,必须使用global语句。

global VarName的表达式会告诉Python, VarName是一个全局变量,这样Python就不会在局部命名空间里寻找这个变量了。

例如,咱们在全局命名空间里定义一个变量money。咱们再在函数内给变量money赋值,而后Python会假定money是一个局部变量。然而,咱们并无在访问前声明一个局部变量money,结果就是会出现一个UnboundLocalError的错误。取消global语句的注释就能解决这个问题

Money = 2000
def AddMoney():
   # 想改正代码就取消如下注释:
   # global Money
   Money = Money + 1
 
print Money
AddMoney()
print Money

dir()函数

dir()函数一个排好序的字符串列表,内容是一个模块里定义过的名字。

返回的列表容纳了在一个模块里定义的全部模块,变量和函数。以下一个简单的实例:

import Common

list = dir(Common)

print(list)

输出结果:

image

Python中的包

包是一种管理 Python 模块命名空间的形式,采用"点模块名称"。

好比一个模块的名称是 A.B, 那么他表示一个包 A中的子模块 B 。

就好像使用模块的时候,你不用担忧不一样模块之间的全局变量相互影响同样,采用点模块名称这种形式也不用担忧不一样库之间的模块重名的状况。

这样不一样的做者均可以提供 NumPy 模块,或者是 Python 图形库。

不妨假设你想设计一套统一处理声音文件和数据的模块(或者称之为一个"包")。

现存不少种不一样的音频文件格式(基本上都是经过后缀名区分的,例如: .wav,:file:.aiff,:file:.au,),因此你须要有一组不断增长的模块,用来在不一样的格式之间转换。

而且针对这些音频数据,还有不少不一样的操做(好比混音,添加回声,增长均衡器功能,建立人造立体声效果),所你还须要一组怎么也写不完的模块来处理这些操做。

这里给出了一种可能的包结构(在分层的文件系统中):

sound/                          顶层包
      __init__.py               初始化 sound 包
      formats/                  文件格式转换子包
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  声音效果子包
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  filters 子包
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。

目录只有包含一个叫作 __init__.py 的文件才会被认做是一个包,主要是为了不一些滥俗的名字(好比叫作 string)不当心的影响搜索路径中的有效模块。

最简单的状况,放一个空的 :file:__init__.py就能够了。固然这个文件中也能够包含一些初始化代码或者为(将在后面介绍的) __all__变量赋值。

用户能够每次只导入一个包里面的特定模块,好比:

import sound.effects.echo

这将会导入子模块:mod:song.effects.echo。 他必须使用全名去访问:

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

还有一种导入子模块的方法是:

from sound.effects import echo

这一样会导入子模块:mod:echo,而且他不须要那些冗长的前缀,因此他能够这样使用:

echo.echofilter(input, output, delay=0.7, atten=4)

还有一种变化就是直接导入一个函数或者变量:

from sound.effects.echo import echofilter

一样的,这种方法会导入子模块:mod:echo,而且能够直接使用他的:func:echofilter函数:

echofilter(input, output, delay=0.7, atten=4)

注意当使用from package import item这种形式的时候,对应的item既能够是包里面的子模块(子包),或者包里面定义的其余名称,好比函数,类或者变量。

import语法会首先把item看成一个包定义的名称,若是没找到,再试图按照一个模块去导入。若是还没找到,恭喜,一个:exc:ImportError 异常被抛出了。

反之,若是使用形如import item.subitem.subsubitem这种导入形式,除了最后一项,都必须是包,而最后一项则能够是模块或者是包,可是不能够是类,函数或者变量的名字。


从一个包中导入*

设想一下,若是咱们使用 from sound.effects import *会发生什么?

Python 会进入文件系统,找到这个包里面全部的子模块,一个一个的把它们都导入进来。

可是很不幸,这个方法在 Windows平台上工做的就不是很是好,由于Windows是一个大小写不区分的系统。

在这类平台上,没有人敢担保一个叫作 ECHO.py 的文件导入为模块:mod:echo仍是:mod:Echo甚至:mod:ECHO。

(例如,Windows 95就很讨厌的把每个文件的首字母大写显示)并且 DOS 的 8+3 命名规则对长模块名称的处理会把问题搞得更纠结。

为了解决这个问题,只能烦劳包做者提供一个精确的包的索引了。

导入语句遵循以下规则:若是包定义文件 __init__.py 存在一个叫作 __all__ 的列表变量,那么在使用 from package import * 的时候就把这个列表中的全部名字做为包内容导入。

做为包的做者,可别忘了在更新包以后保证 __all__ 也更新了啊。你说我就不这么作,我就不使用导入*这种用法,好吧,没问题,谁让你是老板呢。这里有一个例子,在:file:sounds/effects/__init__.py中包含以下代码:

__all__ = ["echo", "surround", "reverse"]

这表示当你使用from sound.effects import *这种用法时,你只会导入包里面这三个子模块。

若是__all__真的而没有定义,那么使用from sound.effects import *这种语法的时候,就*不会*导入包:mod:sound.effects里的任何子模块。他只是把包:mod:sound.effects和它里面定义的全部内容导入进来(可能运行:file:__init__.py里定义的初始化代码)。

这会把 :file:__init__.py里面定义的全部名字导入进来。而且他不会破坏掉咱们在这句话以前导入的全部明确指定的模块。看下这部分代码:

import sound.effects.echo
import sound.effects.surround
from sound.effects import *

这个例子中,在执行from...import前,包:mod:sound.effects中的echo和surround模块都被导入到当前的命名空间中了。(固然若是定义了__all__就更没问题了)

一般咱们并不主张使用*这种方法来导入模块,由于这种方法常常会致使代码的可读性下降。不过这样倒的确是能够省去很多敲键的功夫,并且一些模块都设计成了只能经过特定的方法导入。

记住,使用from Package import specific_submodule这种方法永远不会有错。事实上,这也是推荐的方法。除非是你要导入的子模块有可能和其余包的子模块重名。

若是在结构中包是一个子包(好比这个例子中对于包:mod:sound来讲),而你又想导入兄弟包(同级别的包)你就得使用导入绝对的路径来导入。好比,若是模块:mod:sound.filters.vocoder 要使用包:mod:sound.effects中的模块:mod:echo,你就要写成 from sound.effects import echo。

from . import echo
from .. import formats
from ..filters import equalizer

不管是隐式的仍是显式的相对导入都是从当前模块开始的。主模块的名字永远是"__main__",一个Python应用程序的主模块,应当老是使用绝对路径引用。

包还提供一个额外的属性,:attr:__path__。这是一个目录列表,里面每个包含的目录都有为这个包服务的:file:__init__.py,你得在其余:file:__init__.py被执行前定义哦。能够修改这个变量,用来影响包含在包里面的模块和子包。

这个功能并不经常使用,通常用来扩展包里面的模块。

相关文章
相关标签/搜索