绪言:
- http://blog.youkuaiyun.com/pipisorry/article/details/43313197
- 1. python程序由包(package)、模块(module)和函数组成。
- 2. 包是由一系列模块组成的集合。当不同作的模块进行按文件夹分类后再组成一个整体的库,可以称为包。为了让Python将目录当做内容包,目录中必须包含__init__.py文件,用于标识当前文件夹是一个包。最简单的情况下,只需要一个空的__init__.py文件即可。包就是一个完成特定任务的工具箱,包的作用是实现程序的重用。包导入会让模块扮演的角色更为明显,也使代码更具有可读性。
- 3. 模块是处理某一类问题的函数和类的集合,由代码、函数和类组成。函数是一段可以重复多次调用的代码。模块把一组相关的函数或代码组织到一个文件中,一个文件即是一个模块。每个模块文件是一个独立完备的命名空间,一个模块文件不能看到其他文件定义的变量名,除非它明确地导入了那个文件,模块文件起到了最小化命名冲突的作用
1、模块
- 模块是一个包含有一系列数据,函数,类等组成的程序组
- 模块是一个文件,模块文件名通常以‘.py’结尾
2、模块的作用:
- 让一些相关的数据,函数,类等有逻辑的组织在一起,使逻辑结构更加清晰,
- 我们可以使用模块将大型程序分解为可管理的小型文件,方便管理和应用。
- 模块中的变量,函数和类等可提供给其他模块或程序使用,重用性强。
3、模块的分类:
- 内置模块(builtins)在解析器的内部是可以直接使用
- 标准库模块,安装python时已安装可直接使用
- 第三方模块(通常为开源),需要自己安装
- 用户自己编定的模块(可以作为其他人的第三方模块)
4、模块的导入 :
- 当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。
- import语句搜索模块的路径顺序:
- 1、搜索程序运行时的路径(当前路径)
- 2、sys.path提供的路径(利用这个可以查找到路径。)
- 3、搜素内置模块
- 注意:
- 在模块导入时,模块所有的语句都会执行。
-
一个模块只会被导入一次,不管你执行了多少次import。
- 模块的重新加载:
- import mymod
- import imp
- imp.reload(mymod) #重新加载mymod模块
- 模块被导入和执行的过程:
- 1、先搜索相关路径找模块(.py文件)
- 2、判断是否有此模块对应的.py文件,如果.pyc文件闭.py文件新,则直接加在.pyc文件
- 3、否则用模块.py 文件生成.pyc并加载执行。
- pyc模块的编译:
- mymod.py-----编译-->mymod.pyc -----解释执行--->
>>> import imp
>>> import my_module
这段代码被执行了
>>> import my_module
>>> imp.reload(my_module)
这段代码被执行了
<module 'my_module' from '.\\my_module.py'>
- import 语句
- 语法: import 模块名 [ as 模块新名1 ] ,模块名2[as 模块新名2],.........
- 作用:将一个模块整体导入到当前模块中
- 属性用法:模块名.属性名
- help(obj) 可以查看模块的文档字符串
import math # 导入数学模块
import sys,os #导入sys 和 os 模块
import copy as cp #给copy起一个新的名字cp
- from import 语句
- 语法:
- from 模块名 import 模块属性名 [as 属性名新名1],模块属性名2 [as 属性名新名2]....
- 作用:将某模块的一个或多个属性导入到单枪模块的作用域
from math impor pi
from math import sin
from math import factorial as fac
- from import * 语句(可能会有重名)
- 语法: from 模块名 import *
- 作用: 将某模块的所有属性导入到当前的模块
from math import *
s = sin(pi/2)
5、模块的一些属性
- 模块的文档字符串:(保存在doc属性里面)
- 模块内第一个没有赋值给任何变量的字符串的文档字符串,
- 模块的__doc__属性:
- 用于绑定模块文档字符串
- __file__属性
- 绑定模块对应的文件路径
- __name__属性:
- 用来记录模块的自身名字、
- 作用:1、记录模块名 2、判断是否为主模块
- 说明:1、当此模块作为主模块(也就是第一个)运行时,__name__绑定‘__main__’
- 2、当此模块不是主模块时,__name__绑定模块名(文件名去掉.py后缀)
"""这是一个模块名字
这个模块是干什么干什么的。
"""
def hello():
"""这是一个hello函数的名字
这个模块有这样的功能。
"""
pass
print(__file__)
print("++++++++")
print(__doc__)
print("++++++++++")
print(help(__name__))
运行结果:
C:\Users\Administrator\Documents\Aptana Studio 3 Workspace\Demo1\123.py
++++++++
这是一个模块名字
这个模块是干什么干什么的。
++++++++++
Help on module __main__:
NAME
__main__ - 这是一个模块名字
DESCRIPTION
这个模块是干什么干什么的。
FUNCTIONS
hello()
这是一个hello函数的名字
这个模块有这样的功能。
DATA
__annotations__ = {}
FILE
c:\users\administrator\documents\aptana studio 3 workspace\demo1\123.py
None
- 模块的__all__列表:
- 模块中的__all__列表是一个用来存放可导入属性的字符串列表
- 作用:限定当用 from xxx import * 语句导入时,只导入__all__列表内的属性。
#__all__列表限定其他模块再用 from 模块名 import * 导入时
#只导入 __all__列表内部限定的。
__all__ = ['myfun1','myfun3','name1']
print(dir())
def myfun1():
print('myfun1被调用')
def myfun2():
print('myfun2被调用')
def myfun3():
print('myfun2被调用')
name1 = 'xiaomimg'
name2 = 'xiaohong'
- 模块的隐藏属性:
- 模块中以‘__’开头的属性,在from XXX import * 导入时将不被导入,通常称这些属性为隐藏属性。
'''此模块示意隐藏属性以及其用法
以‘__'开头的变量在被from xxx import *
(其它导入不算)导入时,不被导入。
'''
def f():
print('f函数被调用')#导入
def _f():#不被导入
print('f函数被调用')
def __f():#不被导入
print('f函数被调用')
name = 'aa'#导入
_name = 'bbbb'#不被导入
__name = 'cccc'#不被导入
6、dir 函数
- dir([对象]) 返回一个字符串列表
- 作用:
- 1、如果没有参数调用,则返回当前作用域内所有变量的列表。
- 2、如果给定一个对象作为参数,则返回这个对象的所在变量(属性)列表
- 对于一个模块,返回这个模块的全部变量
- 对于一个类对象,返回类对象的所有变量,并递归基类对象的所有变量
- 对于其他对象,返回所有变量、类变量和基类变量
7、包(模块包) package
- 包是将模块以文件夹的组织形式进行分组管理的方法
- 我们通常不会把所有的文件都存储在同一个地方。我们使用一个组织良好的目录层次结构,以方便访问。相似的文件保存在同一目录中,例如,我们可以将所有歌曲保留在“music”目录中。与此类似,Python具有用于目录的软件包和用于文件的模块。随着我们的应用程序规模越来越大,带有许多模块,我们将相似的模块放在一个包中,而将不同的模块放在不同的包中。这使项目(程序)易于管理且概念清晰。
- 类似地,由于目录可以包含子目录和文件,因此Python程序包可以具有子程序包和模块。
- 目录必须包含一个名为 __init__.py 的文件,Python才能将其视为一个包。该文件可以保留为空,但是我们通常将该程序包的初始化代码放入此文件中。
- __init__.py 文件
- __init__.py 是常规包内必须存在的文件
- __init__.py 会在包加载时被自动调用
- 作用:1、编写此包的内容
- 2、在内部填写包的文档字符串
- __init__.py 内的 __all__列表:
- 作用:用来记录此包中有哪些包或模块需要在from import *语句导入时被导入。
- 说明:__all__列表只在from xxx import *语句中起作用
- 这是一个实例。假设我们正在开发一个游戏,则可能的包和模块组织如下图所示。
- 作用:1、将一系列模块进行分类管理,有利于访问命名冲突
- 2、可以在需要时加载一个或部分模块,而不是全部模块
8、包的导入
- 包的导入语法:
- #同模块的导入规则相同
- import 包名 [as 包别名]
- import 包名.模块名 [as 模块新名]
import Game.Level.start
- from 包名 import 模块名[as 模块新名]
- from 包名.子包名 import 模块名[as 模块新名]
- from 包名.子包名.模块名 import 属性名 [as 属性新名]
from Game.Level import start
- from 包名 import *
- from 包名.子包名 import *
from Game.Level import *
https://www.runoob.com/python3/python3-module.html
设想一下,如果我们使用 from sound.effects import *会发生什么?
Python 会进入文件系统,找到这个包里面所有的子模块,一个一个的把它们都导入进来。
但是很不幸,这个方法在 Windows平台上工作的就不是非常好,因为Windows是一个大小写不区分的系统。
在这类平台上,没有人敢担保一个叫做 ECHO.py 的文件导入为模块 echo 还是 Echo 甚至 ECHO。
(例如,Windows 95就很讨厌的把每一个文件的首字母大写显示)而且 DOS 的 8+3 命名规则对长模块名称的处理会把问题搞得更纠结。
为了解决这个问题,只能烦劳包作者提供一个精确的包的索引了。
导入语句遵循如下规则:如果包定义文件 __init__.py 存在一个叫做 __all__ 的列表变量,那么在使用 from package import * 的时候就把这个列表中的所有名字作为包内容导入。
作为包的作者,可别忘了在更新包之后保证 __all__ 也更新了啊。你说我就不这么做,我就不使用导入*这种用法,好吧,没问题,谁让你是老板呢。这里有一个例子,在:file:sounds/effects/__init__.py中包含如下代码:
如果 __all__ 真的没有定义,那么使用from sound.effects import *这种语法的时候,就不会导入包 sound.effects 里的任何子模块。他只是把包sound.effects和它里面定义的所有内容导入进来(可能运行__init__.py里定义的初始化代码)。
这会把 __init__.py 里面定义的所有名字导入进来。并且他不会破坏掉我们在这句话之前导入的所有明确指定的模块
通常我们并不主张使用 * 这种方法来导入模块,因为这种方法经常会导致代码的可读性降低。不过这样倒的确是可以省去不少敲键的功夫,而且一些模块都设计成了只能通过特定的方法导入。
记住,使用 from Package import specific_submodule 这种方法永远不会有错。事实上,这也是推荐的方法。除非是你要导入的子模块有可能和其他包的子模块重名。
如果在结构中包是一个子包(比如这个例子中对于包sound来说),而你又想导入兄弟包(同级别的包)你就得使用导入绝对的路径来导入。比如,如果模块sound.filters.vocoder 要使用包 sound.effects 中的模块 echo,你就要写成 from sound.effects import echo。
- 包的相对导入:包内模块的相互导入
- 语法: from 相对路径包或模块import 属性或模块
- from 相对路径包或模块 import *
- 说明:
- 包的相对导入不能用于 import xxx 语句中
- 相对路径:
- ·代表当前目录
- ··代表上一级目录
- ···代表上二级目录 以此类推
- 注:相对导入时不能超出包的外部。
from .open import hello #假设有hello这个函数
from ..Sound import play