一、Python程序的结构
包 [ 模块 [ 类 [ 函数 [ 变量等 ] ] ] ]
二、模块
模块简介:
模块是python组织代码的基本方式。
一个脚本可以导入到另一个脚本中运行,因此.py文件就是模块
模块名与脚本名相同 (注意!没有.py后缀)
调用模块方法:
import 模块名
import 模块名 as 模块重命名 #一般重命名为更方便理解的名字,为了后期维护
from 模块名 import 函数 #再用该函数将不再声明模块名。如:function()。但是其会造成代码可读性较差。
from 模块名 import * #导入模块下所有的函数
调用模块规则:
模块名.函数 #使用模块下的函数。若模块下没有该函数则报错
1、先在当前目录下寻找要导入的模块。
2、如果当前目录下没有,则到系统模块目录下寻找。(Lib目录)
3、如果上条没有。则到site-packages目录下寻找。(Pytho37\Lib\site-packages)
4、如果上条没有。则到环境变量(PYTHONPATH)设置的目录下寻找。
5、如果都没有,则报错
模块属性介绍:
1、__name__属性。注意左右各是两个下划线。下同。
该属性在此处代表当前模块名字,如果当前程序正在被使用,则__name__的值为__main__。常在调试代码时用到。
用法:通常是加一个条件语句来测试该模块的功能。
2、__doc__属性。
Python中的模块是一个对象,而每一个对象都会有一个__doc__属性。该属性用来描述该对象的作用。
用法:直接输出该属性即可。同时它可以输出文档字符串的内容。
模块的内置函数:
内联模块(buildin模块)中定义了许多在软件开发过程中常用的函数。
filter()函数
该函数可以对序列做过滤处理。就是用一个函数来过滤一个序列,把序列的每一项都传递到过滤函数中。通过返回结果是否为True来过滤。
用法:filter(过滤函数,被过滤序列)
reduce()函数
该函数可以实现连续处理功能。例如:累加
用法:reduce(函数名,待处理序列)
map()函数
该函数可以对多个序列中的每个元素执行相同的操作,并返回一个与输入序列长度相同的列表。
用法:map(函数名,待处理序列) #可以接收多个待处理序列。长度不一时短序列后面补None
dir()函数:
该函数返回一个列表,列表容纳了在一个模块里定义的所有模块、变量和函数。
#! /usr/bin/python
# -*- coding:utf-8 -*-
import math
content = dir(math)
print (content)
代码执行结果如下所示:
三、包
包简介:
python的模块可以按目录组织为包。就是很多功能类同模块放一起。
举例: 安装目录Lib下的sqlite3文件夹就是一个包,用于数据库相关操作。
创建包:
创建一个名字为包名的文件夹
在该文件夹下创建一个__init__.py
的文件 ----------------注意!那个是前后双下划线。这是包的标志
根据需要在该文件夹下存放脚本文件(模块)
包的调用:
import 包名.模块名
四、代码实例
调用执行环境应和模块所在环境在同一目录下!
第一个代码文件:calculate.py
#! /usr/bin/python
# -*- coding:utf-8 -*-
def add(x,y):
"doc属性描述字符串在这里"
return x+y
def sub(x,y):
return x-y
if __name__ == "__main__": #代表被直接执行,否则代表被调用,不执行下方代码
print (add(3,4))
print (sub(7,6))
print (add.__doc__) #输出描述字符串
print (add(*[8,9])) #该函数有几个参数,此处就写几个参数。返回17
#python3移除了apply用法,该行代码等价于python2中的:
#print apply(add,[8,9])
-----------------------------------------------------------------
输出结果如下:
7
1
doc属性描述字符串在这里
17
第二个代码文件:transfer.py
#! /usr/bin/python
# -*- coding:utf-8 -*-
import calculate #如果模块在其他目录下,将运行环境转移到其他目录即可
import calculate as addorsub #一般重命名为更方便理解的名字,为了后期维护
from calculate import add #只导入calculate.py中的add函数
from functools import reduce
#测试__name__属性
if __name__=='__main__':
print ("是主程序")
else:
print ("不是主程序")
#测试__doc__属性。输出描述字符串
print (__doc__)
#测试reduce函数
s=[1,2,3,4,5,6,7,8,9]
print (reduce(add,s)) #此处实现累加功能
#常规调用模块中的函数
x=calculate.add(1,2)
print (x)
x=addorsub.add(1,2) #注意是重命名后的
print (x)
x=add(1,2)
print (x)
-----------------------------------------------------------------
输出结果如下:
doc属性描述字符串在这里
17
是主程序
None
45
3
3
3
代码实例:
#! /usr/bin/python
# -*- coding:utf-8 -*-
#filter函数
str=[-1,-2,-3,-4,1,2,3,4,5,6]
def guolv(x):
if x>=-1:
return x
print (list(filter(guolv,str))) #过滤,返回过滤后的新序列[-1,1,2,3,4,5,6]
# python2中这样写
# print filter(guolv,str)
#map函数
def add1(a):
return a+1
def add2(a,b):
return a+b
def add3(a,b,c):
return a+b+c
a1=[1,2,3,4]
a2=[1,2,3,4]
a3=[1,2,3,4]
# Python3中的写法
print (list(map(add1,a1))) #输出:[2,3,4,5]
print (list(map(add2,a1,a2))) #输出:[2,4,6,8]
print (list(map(add3,a1,a2,a3))) #输出:[3,6,9,12]
# python2中这样写
# print map(add1,a1) #输出:[2,3,4,5]
# print map(add2,a1,a2) #输出:[2,4,6,8]
# print map(add3,a1,a2,a3) #输出:[3,6,9,12]
-----------------------------------------------------------------
输出结果如下:
[-1, 1, 2, 3, 4, 5, 6]
[2, 3, 4, 5]
[2, 4, 6, 8]
[3, 6, 9, 12]
五、浅拷贝和深拷贝
背景:
python中以存储数据为基准,不同变量若值相同,则存储相同地址空间,一旦一个变量值变化,另一个变量值相应变化目标:
将其值拷贝出来,使得一个变量值变化,另一个变量保持不变
浅拷贝:
对引用的拷贝。只拷贝父对象。
以拷贝一变量为例。只拷贝了变量名,变量名存储空间变化,使其具有相同值的两个变量名占用不同的存储空间,而变量值存储空间不变。
若一变量可变值(原始值)变化则另一变量值随之变化。可变值之外的值变化对方不受影响。深拷贝:
对对象资源的拷贝。
以拷贝一变量为例。拷贝了变量的值,变量名和它的值的地址都变化了。修改一变量任意值对方不受影响。
代码实例:
#! /usr/bin/python
# -*- coding:utf-8 -*-
import copy #调用拷贝模块
a=[1,2,3,['a','b','c']]
b=a #b和a完全相同
c=copy.copy(a) #浅拷贝a。copy模块的copy函数
a.append('d') #变量a和b变化。多了一个字符
print (c) #变量c不变
a[3].append('d') #改变原始值
print (c) #变量a可变值(原始值)变化,变量c随之变化
d=copy.deepcopy(a) #深拷贝a。copy模块的deepcopy函数
a.remove(1) #删除原始数据1。原始值变化
print (a) #变量a变化
print (d) #变量d不受影响
-----------------------------------------------------------------
输出结果如下:
[1, 2, 3, ['a', 'b', 'c']]
[1, 2, 3, ['a', 'b', 'c', 'd']]
[2, 3, ['a', 'b', 'c', 'd'], 'd']
[1, 2, 3, ['a', 'b', 'c', 'd'], 'd']