函数
函数的定义
将经常要用到的代码封装称为函数,也就是可重复利用的代码块。
函数的创建与调用
定义函数,使用def关键字。
语法
def functionname(parameterlist):
functionbody|pass|...
'''
parameterlist:可选参数,如果有多个使用逗号分隔
functionbody:函数体,函数被调用要执行的功能代码,如果定义一个什么也不做的函数,可以使用pass语句作为占位符
'''
案例
def filterchar(string):
'''功能,过滤指定字符(如黑客)
并将过滤后的结果输出,没有返回值
'''
import re
pattern = r'(黑客)|(抓包)|(Trojan)'
sub = re.sub(pattern,'****',string)
print(sub)
#调用函数
about = '我是一名程序员,喜欢看黑客方面的图书,想研究一下Trojan。'
filterchar(about) #输出 我是一名程序员,喜欢看****方面的图书,想研究一下****。
参数传递
分为形式参数跟实际参数;
形式参数:相当于占位,用来接收实参传递的值(函数定义时,参数列表中的参数就是形参)
实际参数:真实传递的参数(函数调用时,传递进来的参数就是实参)
当实参为不变对象时(如字符串),进行的是值传递,改变形参的值,实参的值不变;
当实参为可变对象时(如列表),进行的是引用传递,改变形参的值,实参也发生改变;
案例
def demo(obj): #这里的参数就是形参,相当于占位
print('原值:',obj)
obj += obj
#调用函数
print('='*5,'值传递','='*5)
mot = 'python天下第一。'
print('函数调用前:',mot)
demo(mot) #这里的参数就是实参
print('函数调用后:',mot) #可以发现采用不可变对象字符串,改变了形参的值,实参没有发生变化
print('='*5,'引用传递','='*5)
list1 = ['赵飞','李萌','刘翔']
print('函数调用前:',list1)
demo(list1)
print('函数调用后:',list1) #可以发现采用可变对象列表,改变了形参的值,实参也发生了改变
'''
---------------脚本执行结果--------------------
===== 值传递 =====
函数调用前: python天下第一。
原值: python天下第一。
函数调用后: python天下第一。
===== 引用传递 =====
函数调用前: ['赵飞', '李萌', '刘翔']
原值: ['赵飞', '李萌', '刘翔']
函数调用后: ['赵飞', '李萌', '刘翔', '赵飞', '李萌', '刘翔']
'''
1、位置参数
位置参数也称为必备参数,调用时的数量和位置必须和定义时是一样的。
案例
def person(name,age):
print('{}的年龄是{}'.format(name,age))
#参数数量必须与定义的一致
person('赵飞',18)
person('赵飞',18,'喜欢馒头') #报错
#参数位置必须一致
person(18,'赵飞') #name取的时18,age取的是赵飞
2、关键字参数
在函数调用时使用形参的名字来确定输入参数的值,不需要与形参的位置一致,使调用函数传递参数更加灵活方便。
案例
def person(name,age):
print('{}的年龄是{}'.format(name,age))
person(age=18,name='赵飞')
3、为参数设置默认值
当没有传入参数时,可直接使用定义函数时设置的默认值。
注意:在定义函数时,指定默认的形参必须在所有参数的最后。
案例
def add(a,b=10,c=4):
print('和为:',a+b+c)
add(5,5) #此时的a=5 b=5 c=4
add(5,c=8) #此时的a=5 b=10 c=8
'''
可以看到,在没有指定参数c时,使用的是默认值c=4,参数是按顺序传入的
可以指定c=8,来指定传入的c参数为8
'''
4、可变参数
也称为不定长参数,即传入函数的实际参数可以是0个,一个,或任意个。
分为两种情况定义
第一种情况:
*parameter
表示能接收任意多个实际参数并放入一个元组中。
案例
def printgirl(*name):
print('\n我喜欢的小姐姐有:')
print(name) #打印接收参数
for item in name:
print(item)
printgirl('刘亦菲')
printgirl('刘亦菲','唐嫣','陈瑶')
'''
---------------脚本执行结果--------------------
我喜欢的小姐姐有:
('刘亦菲',)
刘亦菲
我喜欢的小姐姐有:
('刘亦菲', '唐嫣', '陈瑶')
刘亦菲
唐嫣
陈瑶
'''
案例
注意:如果包括位置参数,则需要定义在可变参数前。
def print_1(name,*args):
print(name,'喜欢喝',args)
print(name,'喜欢喝',*args)
print_1('飞飞','白开水','牛奶','奶茶')
'''
---------------脚本执行结果------------------
飞飞 喜欢喝 ('白开水', '牛奶', '奶茶')
飞飞 喜欢喝 白开水 牛奶 奶茶
'''
#如果要传入列表,则需要在实参前加**,表示将列表拆成元素,在装入元组中
def func1(name,*args):
print(args) #输出('html', 'mysql', 'python')
if len(args)>0:
for i in args:
print('{}学过了{}'.format(name,i))
else:
print('没有学过任何课程!')
courses = ['html','mysql','python']
func1('飞飞',*courses)
'''
---------------脚本执行结果--------------------
('html', 'mysql', 'python')
飞飞学过了html
飞飞学过了mysql
飞飞学过了python
'''
第二种情况:
**parameter
接收任意多个显式赋值的实际参数,并放入一个字典中。
案例
def func(**kwargs):
print(kwargs)
func(a=1,b=2,c=3) #输出 {'a':1,'b':2,'c':3}
dict1={'001':'python','002':'java','003':'c语言'}
func(**dict1) #输出 {'001': 'python', '002': 'java', '003': 'c语言'}
'''
如果要传入字典,则需要在实参前加**,表示将字典拆成键值对,在装入形参成为字典
'''
#打印每位同学的姓名和年龄
students = {'001':('刘亦菲',18),'002':('景甜',19),'003':('唐嫣',20)}
def print_boy(who,**persons):
print('{}喜欢的小姐姐是:'.format(who))
if isinstance(persons,dict):
for name,age in persons.values():
print('{}同学的年龄是:{}'.format(name,age))
#调用
print_boy('我',**students)
返回值
在函数体内使用return语句为函数指定返回值,返回值可以是任意类型;
return语句一执行,就会结束函数,不在执行后续内容;
如果返回多个值,result中保存的是一个元组;
案例
def add(a,b):
result = a+b
return '{}+{}={}'.format(a,b,result)
print(add(1,2)) #输出 1+2=3
#如果return跟多个值会放入元组中
def func1(a,b,c):
return a,b,c
print(func1(1,2,3))#输出 (1, 2, 3)
#也可以将多个值依次赋值
def func2(a,b,c):
return a,b,c
x,y,z=func2(1,2,3)
print(type(x)) #输出 <class 'int'>
print(x,y,z)#输出 1 2 3
函数的嵌套
函数可以互相嵌套使用;
案例
#定义生成验证码函数
import random
def generate_checkcode():
l = '0123456789abcdefghijklmnopqrstyvwxyzABCDEFGHIJKLMNOPQRSTYVWXYZ'
code = ''
for i in range(5):
ran =random.randint(0,len(l)-1)
code += l[ran]
return code
#定义用户登录函数
def login():
username = input('输入用户名:')
password = input('输入密码:')
code =generate_checkcode() #调用生成验证码函数
input_code=input('验证码为{}\n请输入你的验证码:'.format(code))
if input_code.lower() == code.lower():
if username == 'tz' and password == '123456':
print('登录成功!')
else:
print('用户名或密码不正确!')
else:
print('验证码输入不正确!')
login() #调用函数
变量的作用域
变量的作用域指程序代码能够访问该变量的区域,如果超出该区域,访问就会报错。
分为局部变量和全局变量。
1、局部变量
函数内部定义,只在函数内部有效,可以在函数内部修改;
案例
#定义全局变量name
name = '小月月'
def func1():
name = '小天才' #定义局部变量
name += '会弹吉他'
print(name) # 就近原则,先访问函数内部的name
def func2():
name +='会弹琴' # 会报错,不允许修改全局变量
print(name)
2、全局变量
在函数外定义,函数内外部都能访问到。
不可变变量不能在函数内部修改,除非加上关键字global
,申明为全局变量才能修改,如字符串;
在函数外部定义的可变变量可以在函数内部修改,无需加global,如列表等
案例
#定义全局变量name
name = '小月月'
def func1():
name = '小天才' #定义局部变量
name += '会弹吉他'
print(name) # 就近原则,先访问函数内部的name
def func2():
global name
name +='会弹琴'
print(name) # 输出 小月月会弹琴
#可变变量修改不需要声明global
list1 = ['刘亦菲','章子怡','景甜']
def func1():
print(list1)
def func2():
list1.append('范冰冰')
print(list1)
func2()
func1()
'''
可以看到未在函数内部声明global,先运行func2(),修改了可变变量列表;
在运行func1()可以看到全局变量list1已被修改
---------------脚本执行结果--------------------
['刘亦菲', '章子怡', '景甜', '范冰冰']
['刘亦菲', '章子怡', '景甜', '范冰冰']
'''
匿名函数
指没有名字的函数,通常只使用一次;使用lambda表达式创建匿名函数。
语法
result = lambda (arg1,arg2,...,argn):expression
'''
expression:必选参数,相当于函数体
'''
案例
#定义一个计算圆面积的函数
import math
def circlearea(r):
result = math.pi*r*r
return result
r = 10
print('半径为:',r,'的圆面积为:',circlearea(r))
#out: 半径为: 10 的圆面积为: 314.1592653589793
#使用匿名函数求圆面积
import math
r = 10
result = lambda r:math.pi*r*r #此时的result是一个lambda对象
print('半径为:',r,'的圆面积为:',result(r))
#out: 半径为: 10 的圆面积为: 314.1592653589793
案例集合
一些可以练手的例子
#定义一个产生范围1-20的随机数的函数
import random
def genrate_random(num):
for i in range(num):
ran=random.randint(1,20) #随机数范围1-20
print(ran)
num=input('请输入产生随机数的个数:')
genrate_random(int(num))
#写一个函数求列表中的最大值
#找最大值
def max_find(list1):
big_num = 0
for i in range(0,len(list1)-1):
if big_num < list1[i]:
big_num =list1[i]
print(big_num)
list1=[2,3,8,58,2]
max_find(list1)
#找出最大值方法二
def max(iterable):
max = iterable[0]
for i in iterable:
if i >max:
max=i
print('最大值是:',max)
list1 = [2,3,4,2,1]
max(list1)
#判断传入的参数是列表
def panduan(iterable):
panduan = str(type(list1))
if 'list' in panduan:
print('这是一个列表')
list1 = [2,3,4,2,1]
panduan(list1)
#判断参数是否为列表方法二
#使用isinstance(变量,类型关键字)方法
def panduan(list1):
if isinstance(list1,list):
print('这是一个列表')
panduan(list1)
#验证3次输入账号密码
def yanzheng():
i = 2
while i>=0:
username = input("请输入用户名:")
password = input('请输入密码:')
if username == 'tz' and password == '123':
print('登录成功!')
break
else:
print('账户或密码错误!你还可以输入',i,'次:')
i-=1
yanzheng()
#使用可变参数*args定义一个求和函数
def sum(*args):
sum = 0
if len(args)>0:
for i in args:
sum+=i
print('和为:',sum)
sum(1,2,3,4,5)#传入参数1,2,3,4,5
#输出 和为: 15
学习来自:《python从入门到项目实践》明日科技 第十一章