函数的参数
参数列表:如果函数所实现的需求中涉及到未知项参与运算,就可以将未知项设置为参数。
形式参数:在方法中定义的,用于接收中间参数的值
实际参数:在函数外面定义,实际参与运算的值,就是为了给形式参数赋值
def myprint(n): #n为形参
for x in range(n):
print("你好啊")
myprint(3) #3为实参
位置参数【又称必选参数】
传递参数的顺序与定义的顺序有关,必须按照定义的顺序来进行传递。
传递参数的个数与参数的个数必须保持一致。
def hello(name,money):
print("%s,你掉了%d块钱"%(name,money)) #输出 朋友,你掉了10块钱
hello("朋友",10)
关键字参数
指函数调用的时候,可以通过"键-值"的形式来加以指定,可以清除位置关系。
def hello(name,money):
print("%s,你掉了%d块钱"%(name,money)) #输出 朋友,你掉了10块钱
hello(money = 10,name = "朋友")
注意:当出现位置参数与关键字参数的时候,需要将位置参数写在关键字参数前面
def hello(name,money):
print("%s,你掉了%d块钱"%(name,money)) #输出 朋友,你掉了10块钱
hello(meney = 10,"朋友") #错误,报错
hello("朋友",money=10)
默认参数
定义函数的时候,我们可以给参数提供默认值,调用函数的时候可以传递此参数可以不传,当传递此参数的时候,函数使用传递的参数,若不传递则使用默认值。
优点:方便函数的调用
def hello(name,money = 10):
print("%s,你掉了%d块钱"%(name,money)) #输出 朋友,你掉了10块钱
hello("朋友")
注意:
1.若默认参数与位置参数同时存在的时候,位置参数要写在默认参数的前面
2.给定默认参数的时候,默认参数需要指向不可变对象。
不定长参数
定义函数的时候,我们不确定调用的时候到底会传递多少参数进来【可能传递1个也可能多个或者不传递】
此时我们可以使用不定长参数来解决【不定长参数又包括包裹位置参数与包裹关键字参数】
特点:能处理比声明时候更多的参数【传递多少参数,处理多少参数,不传递不处理】
不定长参数分为两种:
(1).包裹位置参数
使用:*变量名 一般用 *args
功能:可以收集除了必选参数以外剩余的位置参数,按照元组来进行处理
def hello(*args):
print("%s,你掉了%d块钱"%(args)) #输出 朋友,你掉了10块钱
print(args) #输出 ('朋友', 10)
hello("朋友",10)
(2).包裹关键字参数
使用:变量名 一般用kwargs
功能:收集除定义的变量的关键字参数之外,剩余关键字参数。
包裹关键字参数只处理剩余的关键字参数,收集作为字典来进行处理。
def hello(name,**kwargs):
print(name) #输出 朋友
print(kwargs) #输出 {'s1': '我', 's2': '10'}
hello("朋友",hobby1 = "我",hobby2 = "10")
注意:当位置参数【必选参数】,默认参数,包裹位置参数,包裹关键字参数同时存在的情况下,一般的顺序为:
位置参数,默认参数,包裹位置参数,包裹关键字参数
默认参数与包裹位置参数可以根据需求,位置可以调换
匿名函数
定义:指的是一类无须定义标识符【函数名】的函数或者子程序。
在python中定义匿名函数使用lambda来进行定义。
语法:
lambda 参数列表: 表达式
特点:
1.lambda后面的跟的只是一个表达式,结构体比def的简单
2.参数列表可以有多个参数,参数与参数之间使用逗号隔开
3.无须写return,表达式的结果就是该表达式的返回值。
优点:
1.结构简单
2.匿名函数没有名字无须担心函数名的冲突。
匿名函数的调用:
将lambda表达式赋值给一个变量,通过调用变量来调用我们的匿名函数。
func = lambda a,b: a if a>b else b
print(func(10,20)) #输出20
zip函数
语法:zip(iter1,iter2,…)
功能:打包,将可迭代对象中对应位置的元素进行打包,长度取决于最短的那个,返回zipobj打包好的对象,以迭代器的方式返回
list1 = [1,2,3]
list2 = ["hello","hi","你好"]
zipobj = zip(list1,list2)
print(list(zipobj)) #输出[(1, 'hello'), (2, 'hi'), (3, '你好')]
zip(*zipobj)解包
将之前打包的元素进行解包处理,以迭代器方式返回
list1 = [1,2,3]
list2 = ["hello","hi","你好"]
zipobj = zip(list1,list2)
print(list(zip(*zipobj))) #输出 [(1, 2, 3), ('hello', 'hi', '你好')]
装饰器
在代码运行的期间动态的增加功能的方式我们称之为装饰器。
简单的装饰器
def outer(func):
def inner():
#增强的功能
#在内函数中执行func函数
return func()
return inner
在装饰器中,分为外函数与内函数:
外函数(outer):
1.将被装饰的函数传递进来–》func
2.将装饰好的函数返回给调用者 --》inner
内函数:
1.添加动态增加的功能
2.执行被装饰的函数
复杂的修饰器
def outer(func): #func 被装饰的函数
def inner(参数列表):
#添加的功能
return func(参数列表)
return inner
偏函数
将函数的某些值给固定住,给你返回一个新的函数,这个函数就是偏函数的功能。
语法
import functools模块
newfunc = functool.partial(func,参数)
例如
import functools
def func(a,b):
return a*b
int3 = functools.partial(func,b=2)
print(int3(3)) #输出6
回调函数
将函数作为参数传递到另外一个函数中,这个被传递进去,后来又被调用的函数,我们称之为回调函数。
例如
def wake1(time):
print("在%s点,使用揪耳朵的方式叫醒。。。"%time)
def wake2(time):
print("在%s点,使用泼冷水的方式叫醒..."%time)
def wake_server(func,time):
return func(time)
wake_server(wake1,"下午一点五十") #输出 在下午一点五十点,使用揪耳朵的方式叫醒。。。
返回函数
把函数作为返回值返回的时候,我们可以称这个函数为返回函数
例如
def calc_sum(*args):
sum = 0
for i in args:
sum += i
return sum
print(calc_sum(1,2,3)) #输出 6
递归函数
函数在内部是可以调用其他函数的,当被调用的函数是函数自己本身的时候,我们称这个函数为递归函数
思路:
1.写出临界条件:1! = 1
2.找出这次跟上次的关系
3.假设函数可以使用,根据上一次的值,求出本次的结果
例如
###1,2,3,4,5...10之和
def func(n):
if n==1:
return 1
else:
return func(n-1)+n
print(func(10)) #输出55
注意:使用递归函数的时候,一定要注意栈溢出的情况
变量的作用域
程序中变量并不是在任意的地方都能访问,访问范围取决于它在赋值的位置【定义的位置】
局部作用域:在函数中定义的变量,每当函数被调用的时候它都会产生一个新的作用域,这个新的作用域我们称之为局部作用域,在局部作用域中定义的变量,我们称之为局部变量
局部变量起作用的范围就是当前所在的这个函数。
嵌套作用域:又称函数作用域
全局作用域:在模块中定义的变量,并且定义在函数体之外的变量,他们产生的作用域叫做全局作用域,这个变量我们称之为全局变量。
全局变量作用的范围整个.py文件。
内置作用域:系统内部定义的变量产生的作用域,叫做内置作用域。
起作用的范围,所有的.py文件。
搜索变量的优先级:
局部作用域>嵌套作用域>全局作用域>内置作用域,
当这几个作用域中都不存在的时候则报错
例如
mun =100 #全局作用域
def num():
num =120 #嵌套作用域
def func(n):
num = 120 #局部作用域
if n==1:
return 1
else:
return func(n-1)+n
print(__name__) #内置作用域
global关键字
在局部作用域中,不能直接更改全局变量的值,若有需要在局部作用域中更改全局变量,则需要在更改之前对此变量进行声明,使用关键字global进行声明,声明之后变可更改
num1 = 100
def func():
global num1
num1 = 200
print(num1)
func() #输出200
print(num1) #输出200