def CalCirlArea(r): #r为形式参数(形参)
s=3.14*r*r #计算半径为r的圆的面积
print('半径为%.2f的圆的面积为:%.2f'%(r,s))
m=float(input("请输入圆的半径:")) #m为实际参数(实参)
CalCirlArea(m)
def CalRectArea(a,b):
s=a*b
print("边长为%.2f和%.2f的长方形的面积为:%.2f"%(a,b,s))
x=eval(input('请输入长方形的一条边长:'))
y=eval(input('请输入长方形的另一条边长:'))
CalRectArea(x,y)
当实参传递给形参后,如果在函数体中对形参值做修改,则该修改不会影响实参,即实参值不会改变。
当如果实参是列表等对象时,可在函数体中通过形参修改实参列表中对应的元素的值。
def A(x,y):
x=y #将y的值赋给x
def B(ls,idx,val):
ls[idx]=val #将ls中下表为idx的元素值赋为val
a=5
c=[1,2,3]
A(a,10)
print(a) #输出5
A(c,[4,5,6])
print(c) #输出[1,2,3]
B(c,1,[666,999])
print(c) #输出[1, [666, 999], 3]
结果如下:
5
[1, 2, 3]
[1, [666, 999], 3]
默认参数:当调用函数时,若没有为某些形参传递对应实参,则这些形参会自动使用默认参数值。
def StudentInfo(name,country="中国"):
print("姓名:%s,国家:%s"%(name,country))
StudentInfo("小明")
StudentInfo("大卫","美国")
输出结果:
姓名:小明,国家:中国
姓名:大卫,国家:美国
name没有默认参数,所以在调用函数时必须指定实参,否则运行程序会报错。
StudentInfo() #会报错
位置参数:通过位置来体现实参和形参的对应关系
关键字参数:形式为“形参=实参”
位置参数和关键字参数可以混合使用,但是位置参数在前,关键字参数在后!!!
StudentInfo(name="大卫","良好","中国") #则会报错
def StudentInfo(name,chineselevel="良好",country="中国"):
print("姓名:%s,中文水平:%s,国家:%s"%(name,chineselevel,country))
StudentInfo("小明") #未传的实参使用默认参数
StudentInfo("大卫",country="美国")
StudentInfo(country="英国",chineselevel="一般",name="丽娜")
结果如下:
姓名:小明,中文水平:良好,国家:中国
姓名:大卫,中文水平:良好,国家:美国
姓名:丽娜,中文水平:一般,国家:英国
不定长参数:在调用函数时,可以接受任意数量的实参。这些实参在传递给函数时会被封装成元组(位置参数)或字典(关键字参数)形式。
def 函数名([普通形参列表,]*不定长参数名[,普通形参列表]):#*不定长参数名对应的是一组位置参数
函数体,封装成元组
def 函数名([普通形参列表,]**不定长参数名):#**不定长参数名对应的是一组关键字参数
函数体,封装成字典
例子如下:
def StudentInfo1(name,*args):
print("姓名:",name,",其他:",args)
def StudentInfo2(name,**args):
print("姓名:",name,",其他:",args)
def StudentInfo3(name,*args,country="中国"):
print("姓名:",name,",国家:",country,",其他:",args)
StudentInfo1("小明","良好","中国")
StudentInfo2("小明",中文水平="良好",国家="中国")
StudentInfo3("小明",18,"良好","男")
StudentInfo3("大卫",19,"一般","男",country="美国")
姓名: 小明 ,其他: ('良好', '中国')
姓名: 小明 ,其他: {'中文水平': '良好', '国家': '中国'}
姓名: 小明 ,国家: 中国 ,其他: (18, '良好', '男')
姓名: 大卫 ,国家: 美国 ,其他: (19, '一般', '男')
拆分参数列表:如果一个函数所需的参数已经存储在列表、元组或字典中,则可以直接从列表、元组或字典中拆分出来函数所需的这些参数。
def SumVal(*args):
sum=0
for i in args:
sum+=i
print("求和结果为:",sum)
ls=[3,5.2,7,1]
SumVal(ls[0],ls[1],ls[2],ls[3])
SumVal(*ls) #*ls的作用就是把列表ls中所有的元素拆分出来作为函数的实参,等价于SumVal(3,5.2,7,1)
SumVal(3,5.2,7,1)
求和结果为: 16.2
求和结果为: 16.2
求和结果为: 16.2
def StudentInfo(name,chineselevel,country):
print("姓名:%s,中文水平:%s,国家:%s"%(name,chineselevel,country))
d={"country":"中国","name":"小明","chineselevel":"良好"}
StudentInfo(**d) #**d的作用就是把字典d中所有的元素拆分出来作为函数的实参,等价于StudentInfo(country="中国",name="小明",chineselevel="良好")
StudentInfo(country="中国",name="小明",chineselevel="良好")
姓名:小明,中文水平:良好,国家:中国
姓名:小明,中文水平:良好,国家:中国
返回值:将函数的运算结果返回到调用函数的位置,使其结果继续进行其他的运算,应使用return语句
不写return,或写return None(或直接写为return)则表示不返回数据
#零件圆内有一个镂空的长方形,求实际面积
def CalCircleArea(r):
return 3.14*r*r
def CalRectArea(a,b):
return a*b
r1,d1,d2=5,2,2.5
S1=CalCircleArea(r1)
S2=CalRectArea(d1,d2)
S=S1-S2 #同S=CalCircleArea(r1)-CalRectArea(d1,d2)
print("零件面积为:%.2f"%S)
零件面积为:73.50
还可以通过return返回字符串、列表、元组等数据类型
def GetString():
return "你好"
def GetList():
return [1,2,3]
def GetTuple():
return (1,2,3)
def GetElements():
return 1,2,3
print(type(GetString()))
print(GetString())
print(type(GetList()))
print(GetList())
print(type(GetTuple()))
print(GetTuple())
print(type(GetElements()))
print(GetElements())
返回结果:
<class 'str'>
你好
<class 'list'>
[1, 2, 3]
<class 'tuple'>
(1, 2, 3)
<class 'tuple'>
(1, 2, 3)
模块和import语句
要使用另一个模块的某些功能时,可以通过import方式将该模块导入。
import module1
import module2
...
import moduleN
或
import module1,module2,...,moduleN
导入模块后,若要使用模块中定义的标识符,则需要通过“模块.标识符”的方法调用。
案例:
在PrimeNumber.py文件下编写函数,在moduletest.py文件下引用PrimeNumber.py中的函数。
#PrimeNumber.py文件
def GetPrimeNumber(a,b):
if a<b:
for m in range(a,b):
n=2
while n<m:
if m%n==0:
break
else:
n=n+1
else:
if m<=1:
continue #最小的质数为2
else:
print(m,end=" ")
else:
print("\r")
else:
print("请输入合规区间!")
print("寻找质数")
#moduletest.py文件
import PrimeNumber
PrimeNumber.GetPrimeNumber(-2,10)
PrimeNumber.GetPrimeNumber(10,-20)
PrimeNumber.GetPrimeNumber(10,20)
结果如下:
寻找质数
2 3 5 7
请输入合规区间!
11 13 17 19
全局变量__name__
__name__的作用是获取当前模块的名称,如果当前模块是单独执行的,则其__name__的值就是__main__;如果是作为模块导入,则其__name__的值就是模块的名字。
导入模块时,会执行该模块中的脚本。可以通过__name__的值判断当前模块是单独执行还是作为模块导入。
if __name__=="__main__": #如果满足,则表示模块单独执行
执行语句
系统模块,例如sys
import sys
除了使用import将整个模块导入,还可以视同from ...import将模块中的标识符(变量名、函数名等)直接导入当前环境,这样在访问标识符时,就不用指定模块名。语法格式:
from 模块名 import 标识符1,标识符2,...,标识符N
#moduletest.py文件
from PrimeNumber import GetPrimeNumber
GetPrimeNumber(-2,10)
GetPrimeNumber(10,-20)
GetPrimeNumber(10,20)
结果如下:
寻找质数
2 3 5 7
请输入合规区间!
11 13 17 19
导入模块时,不管是“import 模块名”,还是“from 模块名 import 标识符”,都会完全执行被导入模块的全部代码!只不过“from 模块名 import 标识符”,在调用标识符时,可以省略模块名。
如果要导入一个模块的所有标识符,也可以使用“from 模块名 import * ”
如果一个模块定了列表__all__,则“from 模块名 import * ”语句只能导入__all__列表中存在的标识符。
#module1模块的脚本
__all__=["GetString","GetList"]
def GetString():
print("字符串")
def GetList():
print("列表")
def GetTuple():
print("元组")
#module2模块的脚本
from module1 import *
GetString()
GetList()
#GetTuple() #因为该标识符没有在__all__定义的列表里,所以“from module1 import *”没有导入该标识符,会报错“NameError: name 'GetTuple' is not defined”
输出结果:
字符串
列表
利用import和from import导入模块和标识符时,可以使用as为模块或标识符起别名
import module1 as m
m.GetString()
结果如下:
字符串
from module1 import GetString as gs,GetList as gl
gs()
gl()
结果如下:
字符串
列表
包(Package)的作用于操作系统中文件夹的作用相似,利用包可以将多个关系密切的模块组成在一起。
定义一个包,就是创建一个文件夹,并在该文件夹下创建一个__init__.py文件,文件夹的名字就是包名。
另外,可以根据需要在该文件夹下创建一个子文件夹,子文件夹中创建一个__init.py文件,则又形成了一个子包。
模块可以放在任何一个包或子包中,在导入模块时,需要指定所在的包和子包的名字。例如,如果要在导入包A中的模块m,则需要使用“import A.m”
__init__.py可以是一个空文件,也可以包含包的初始化代码或者__all__列表。
如果要使用sound包的effects子包的echo模块,可以通过以下方式导入:
import sound.effects.echo
如果在echo模块中有一个number函数,调用时必须指定完整的名字(包括各层的包名和模块名),即:
sound.effects.eho.number(实参列表)
------
也可以使用from import 方式导入sound包的effects子包的echo模块,如:
from sound.effects import echo
调用echo模块中的函数时,不需要加包名,如:
echo.number(实参列表)
------
也可以使用from import直接导入sound包的effects子包的echo模块中的number函数,如:
from sound.effects.echo import number
调用函数时,不需要加包名和模块,如:
number(实参列表)
猴子补丁:在运行时动态替换已有的代码,而不需要修改原始代码。
def Sun(a,b):
print("Sum函数被调用!")
return a+b
def NewSum(*args):
print("NewSum函数被调用!")
s=0
for i in args:
s=s+i
return s
Sum=NewSum #将NewSum赋予Sum,后面再调用Sum函数,实际上执行NewSum
print(Sum(1,2,3,4,5))
ls=[6,7,8,9]
print(Sum(*ls))
结果如下:
NewSum函数被调用!
15
NewSum函数被调用!
30
第三方模块的获取与安装 一般使用pip工具
以numpy模块为例,在安装numpy之前,可以现在Python环境中输入“import numpy”,此时会得到错误信息:ModuleNotFoundError: No module named 'numpy'
安装命令:pip install numpy
安装成功之后,导入numpy模块没有报错。
变量的作用域:指变量的作用范围,即定义一个变量后,在哪些地方可以使用这个变量。根据作用域的不同,Python的变量可分为局部变量和全局变量。
局部变量:在一个函数中定义的变量就是局部变量(包括形参),其作用域是从定义局部变量的为止至函数结束位置。
全局变量:在所有函数外定义的变量就是全局变量,其在所有函数中都可以使用。
global关键字:在一个函数中使用global关键字,则声明在该函数中使用的是全局变量,而非局部变量。示例如下:
#不使用global关键字
def GlobalVar1():
print("GlobalVar1函数中x的值为:",x)
def GlobalVar2():
x=100 #局部变量
print("GlobalVar2函数中x的值为:",x)
x=20 #定义全局变量x,并赋为20
GlobalVar1()
GlobalVar2()
GlobalVar1()
结果如下:
GlobalVar1函数中x的值为: 20
GlobalVar2函数中x的值为: 100
GlobalVar1函数中x的值为: 20
#使用global关键字
def GlobalVar1():
print("GlobalVar1函数中x的值为:",x)
def GlobalVar2():
global x #声明在该函数中x是全局变量
x=100 #将全局变量修改为100
print("GlobalVar2函数中x的值为:",x)
x=20 #定义全局变量x,并赋为20
GlobalVar1()
GlobalVar2()
GlobalVar1()
结果如下:
GlobalVar1函数中x的值为: 20
GlobalVar2函数中x的值为: 100
GlobalVar1函数中x的值为: 100
nonlocal关键字:函数的定义可以嵌套。通过nonlocal关键字,可以使内层的函数直接使用外层函数中定义的变量。示例如下:
#不使用nonlocal关键字
def outer():
x=10
def inner():
x=20
print("inner函数中x的值为:",x)
inner()
print("outer函数中x的值为:",x)
outer()
结果如下:
inner函数中x的值为: 20
outer函数中x的值为: 10
#使用nonlocal关键字
def outer():
x=10
def inner():
nonlocal x
x=20
print("inner函数中x的值为:",x)
inner()
print("outer函数中x的值为:",x)
outer()
结果如下:
inner函数中x的值为: 20
outer函数中x的值为: 20
递归函数:指一个函数内部通过调用自己来完成一个问题的求解的函数。
编写递归函数计算n的阶乘。
#使用递归方式计算n的阶乘
def fac(n):
if n==1:
return 1
return n*fac(n-1)
x=int(input("n="))
print("n!=",fac(x))
结果如下:
n=5
n!= 120
#使用非递归方式计算n的阶乘
def fac2(n):
f=1
for i in range(1,n+1):
f=f*i
return f
x=int(input("n="))
print("n!=",fac2(x))
结果如下:
n=5
n!= 120
高阶函数:指把函数作为参数的一种函数。
def FunAdd(f,x,y):
return f(x)+f(y)
def Square(x):
return x*x
def Cube(x):
return x*x*x
print("3²+(-5)²=",FunAdd(Square,3,-5))
print("3³+(-5)³=",FunAdd(Cube,3,-5))
结果如下:
3²+(-5)²= 34
3³+(-5)³= -98
提示:函数不仅可以赋给形参,也可以赋给普通变量。赋值后,可以用变量名替代函数名完成函数调用。
def FunAdd(f,x,y):
return f(x)+f(y)
def Square(x):
return x*x
s=Square
print(s(3))
print("3²+(-5)²=",FunAdd(s,3,-5))
结果如下:
9
3²+(-5)²= 34
lambda函数:匿名函数,不使用def定义函数的形式,起作用是能快速定义一个简短的函数。lambda函数的函数体只是一个表达式,通常只能实现比较简单的功能。格式如下:
lambda [参数1[参数2,...,参数n]]:表达式
冒号后面的表达式的计算结果即为lambda函数的返回值。示例如下:
def FunAdd(f,x,y):
return f(x)+f(y)
print(FunAdd(lambda x:x*x,3,-5)) #lambda x:x*x返回x的平方
print(FunAdd(lambda x:x*x*x,3,-5)) #lambda x:x*x*x返回x的立方
结果如下:
34
-98
lambda函数也可以赋给一个变量,然后通过该变量调用对应的lambda函数。如:
fun=lambda x:x*x
print(fun(3))
结果如下:
9