Python 模块
Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。
模块让你能够有逻辑地组织你的 Python 代码段。
把相关的代码分配到一个模块里能让你的代码更好用,更易懂。
模块能定义函数,类和变量,模块里也能包含可执行的代码。
模块,可以供其他人引用,Python不仅可以引用内置的模块,还可以引用很多第三方模块。
这里我们定义一个简单的模块:
module.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
以上两行为标准注释
第 1 行注释: 使该模块可以直接在 Unix/Linux/Mac 上运行
第 2 行注释:表示该模块编码方式为 UTF-8,支持中文,防止乱码
'''
' A test module ' #模块的第一个字符串,被视为文档注释,表明该模块是一个测试模块
__author__ = 'appleyk' #模块内使用__author__变量 ,将作者信息写进去,你懂的。
time = '2017年8月28日10:20:40'#模块内,定义一个时间变量
class A(object): #模块内,定义一个class
def __init__():#构造函数,do nothing
pass
def print_info():
print("I'am class A.")
def Hello(parm): #模块内,定义一个函数
print('Hello %s !' %parm)
Import 模块1,模块2,模块3.....
引入模块
我们新建一个模块test.py:
#!/usr/bin/env Python3
# -*- encoding:UTF-8 -*-
import module,sys
print(module.time)
module.Hello('appleyk')
a = module.A;
a.print_info()
print(sys.path)
test.py引入刚刚我们创建的module模块,同时,我们需要导入内置模块sys
导入模块时,解释器会搜索sys.path列表,这个列表中保存着一系列目录,包括当前脚本语句执行路径,因此,你不用担心你import的模块,我们会使用不了。
我们看下结果:
from modulename Import name1,name2,name3.......
从模块中导入一个指定的部分到当前命名空间中
我们依然拿test.py作为测试模块,将module模块中的功能导入到当前模块中,当我们输入 from module import A时,我们发现:
IDE帮我们呈现了module模块中的结构,类A,函数Hello,变量time和__author__(这个还记得吧,我们的大名!出名就靠它了),这样,我们要使用module中的哪个部分,就导入哪个,如果你使用了,却没用导入模块中对应的部分,我们的程序就会报错:
#!/usr/bin/env Python3
# -*- encoding:UTF-8 -*-
from module import A
from module import __author__
'''
这里,我们只测试导入了模块module中的两个功能
'''
a = A #module模块中的类A已经导入到了当前的命名空间中,这里,我们直接使用,不带前缀
a.print_info();
print(__author__) #这里,我们依然直接使用__author__变量
print(Hello('appleyk')) #我们试图使用module模块中的Hello(parm)函数 会发生什么?
print(module.time) #我们试图用模块.部分的方式,想使用time变量 会发生什么?
针对上面的脚本,我们来看下效果:
from...import*
通配符*,条件反射,全部/All,将一个模块中的所有内容全都导入到当前的命名空间里。
如果我们想要使用module模块中的所有功能,我们要怎么做?一个个import?还是一下子import*?
我们改下上述demo如下:
#!/usr/bin/env Python3
# -*- encoding:UTF-8 -*-
from module import*
from module import __author__
'''
我们导入了module模块中的所有功能, 但是这个属性变量__author__需要单独引入,否则会报NameError异常
'''
a = A #可行
a.print_info();
Hello('appleyk') #可行
print(time) #可行
print(__author__) #可行
看下执行结果是不是我们想要的:
命名空间和作用域
A、变量是拥有匹配对象的名字(标识符)。命名空间是一个包含了变量名称们(键)和它们各自对应的对象们(值)的字典。
B、一个 Python 表达式可以访问局部命名空间和全局命名空间里的变量。
C、如果一个局部变量和一个全局变量重名,我们需要根据作用域去使用它们,作用域不同,产生的效果也不同
D、每个函数都有自己的命名空间。类的方法的作用域规则和通常函数的一样。
E、Python 会智能地猜测一个变量是局部的还是全局的,它假设任何在函数内赋值的变量都是局部的,比如adult函数中的age变量。
因此,如果要在函数内使用全局变量,在使用前我们必须使用 global 语句显示的指定全局变量。
(一)No way(行不通)看下面:
(二)Yes ,It is(来来,一起围观)看下面:
dir()函数
一个排好序的字符串列表,列表里面包含了一个模块里定义过的内容(包括隐藏属性)。
我们用dir函数,输出module模块中的所有内容(我们定义的肯定有,我们没定义的也会输出)
Python中的包 【Package】
我们大部分都了解java的包吧,说白了Python的包也一样,也是一层层的文件目录,比如java的包结构如下:
我们看下,我们的ItemService.java这个在哪放着的(相当于Python的模块.py文件):
简单来说,包就是文件夹,但在Python中,该文件夹下必须存在 __init__.py 文件, 该文件的内容可以为空。__int__.py用于标识当前文件夹是一个包。
如果该文件夹下还有一个文件夹,且这个子文件夹里面也有一个__init__.py文件,我们就称这个子文件夹是子包,也就是包里面套包--> 包、模块、子包的结构
讲包之前,我们先来说下 __name__ 和 __main__
例子:
我们定义一个模块,a.py:
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
def A():
print('我是模块A,初始化完毕!')
print(__name__)
我们直接运行a.py,得到结果:
我们在test.py中导入一下模块a,如下:
#!/usr/bin/env Python3
# -*- encoding:UTF-8 -*-
import a
print(a.__name__)
我们看下test中导入模块a后,输出的a.__name__是什么:
根据上面的特性,我们可以扩展一些功能,比如,我想在模块a中,写上自己的测试代码,却不想当我的模块被别人引用时,别人会触发到这些测试部分的demo,我们可以通过if语句保护我们的测试代码,达到屏蔽的效果,因此,我们对上述模块a.py和test.py进行稍加改动一下:
a.py:
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
def A():
print('我是模块A,初始化完毕!')
if __name__ == '__main__': #如果只是在模块内部使用,我们加上我们的测试代码
print('在方法A初始化模块之前,我们先执行我们的测试代码,这里____________')
A()
else: #如果外部引用本模块,则屏蔽掉我们自己写的测试代码
A()
test.py
#!/usr/bin/env Python3
# -*- encoding:UTF-8 -*-
import a
我们看下分别在模块a中执行,和在模块test中执行有什么区别不:
讲完这个,我们来创建一个Python的包结构,结构目录图如下:
test.py package_appleyk |-- __init__.py |-- module1.py |-- module2.py
对应的文件目录如下:
我们分别看下,__init__.py、module1.py、module2.py和测试test.py的demo部分:
__init__.py:
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
def __init__module():
print('模块初始化',__name__)
if __name__ == '__main__':
print('这里,我们可以在模块内部写上测试代码,留给当前模块调试用:',__name__)
__init__module()
else:
__init__module()
module1.py:
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
def talk1():
print("I'am module one")
module2.py:
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
def talk2():
print("I'am module two")
#!/usr/bin/env Python3
# -*- encoding:UTF-8 -*-
from package_appleyk.module1 import talk1
from package_appleyk.module2 import talk2
talk1()
talk2()
ok,到这,一个包的定义,以及包中模块的引用就结束了,如上,为了举例,我们只在每个.py文件里放置了一个函数,但其实你可以放置许多函数。你也可以在这些文件里定义Python的类,然后为这些类建一个包;你也可以在package_appleyk包中再建一个子包;
我们看下test.py执行的结果:
本篇结束,总结:
可能你没有耐心读完本篇的所有内容,没关系,这并不影响你继续编写我们可爱的Python,但是,如果你想要编写一个结构很严谨,功能很细化,且项目耦合度低的Python工程,模块的运用和使用是至关重要的。
我在学习Python的时候,一开始我是get一个知识点后,就想着立马跳到下一个知识点,这就导致我,知识消化的不够,总感觉自己没有掌握Python,没有领悟透,后来,也就是现在的这种模式,我边学边写,写的过程是痛苦的,因为,一行代码带出的结果很显著,但是用语言去解释为什么的时候,却没有那么容易,基础部分很重要,因此我花了很长的时间去更博,就是为了后面深入Python技术的时候,自己有底气,困难不可怕,可怕的是自己无法正视困难。
一个身在异乡,工作之余还在想着更博的我,对于pyhon,真是满满的爱。
对了,今天情人节,祝天下有情人终成眷属!也祝我和我的宝宝,能够携手一生。