[函数,函数参数的使用、函数对象、闭包函数]

[函数,函数参数的使用]

一、什么是函数?

函数相当于具备某一功能的工具
函数的使用必须 遵循一个原则:
先定义
后调用

二、为何要用函数?

1、组织结构不清晰、可读性差
2、代码冗余
3、可维护性、扩展性差

三、如何用函数

先定义**
三种定义方式
后调用
三种调用方式
返回值
三种返回值的形式**

1、先定义

定义的语法

'''
def 函数名(参数1,参数2……):
"""文档描述"""
函数体
return 值
'''

2、三种定义方式

形式一:无参函数
# def func():
#     print('哈哈哈')
#
# func()

# 定义函数发生的事情
# 1、申请内存空间保存函数体代码
# 2、将上述内存地址绑定给函数名
# 3、定义函数不会执行函数体代码,但是会检测函数体语法

# 调用函数发生的事情
# 1、通过函数名找到函数的内存地址
# 2、通过加括号就是在出发函数体代码的执行

# 示范:
# def bar():  # bar等于函数的内存地址
#     print('from bar')
#
# def foo():
#     bar()
#     print('from foo')
#
# foo()
形式二:有参函数
# def func(x,y):  # x=88  y=99
#     print(x,y)
#
# func(88,99) # 88,99为参数 
形式三:空函数,函数体代码为pass
# def func(x,y):
#     pass

四、三种定义方式各用在何处

1、无参函数的应用场景

# def  interactive():
#     name = input('username: ')
#     age = input('age: ')
#     msg = '名字:{} 年龄{}'.format(name,age)
#     print(msg)
#
# interactive()

2、有参函数的应用场景

# def add(x,y):  #参数 ==>>原材料
#     res = x + y
#     # print(res)
#     return  res  #返回值-->>产品
# # add(2,3)
# res = add(14,12)
# print(res)

3、空函数的应用场景

# def func():
#     pass

五、调用函数的三种形式

# 1、语句形式:只加括号调用函数
#     add()

# 2、表达式形式: # 通常为有返回值
# def add(x,y):  #参数 ==>>原材料
#     res = x + y
#     return  res  #返回值-->>产品

# 赋值表达式:
# res = add(14,12)
# print(res)

# 数学表达式:
# res = add(14,12)*10
# print(res)

# 3、函数调用可以当做参数
# def add(x,y):  #参数 ==>>原材料
#     res = x + y
#     return res  #返回值-->>产品
# res = add(add(14,12),10)
# print(res)

六、函数返回值

return是函数结束的标志,即函数体代码一旦运行运行到return会立刻
终止函数的运行,并且会将return后的值当做本次运行的结果返回:
1、返回None:函数体内没有return
或者return None
# def func():
#     return
# res = func()
# print(res)
2、返回一个值 return 值
# def func():
#     return 10
# res = func()
# print(res)
3、返回多个值:用逗号分隔开多个值,会被return返回成元组
# def func():
#     return 10,'aa',[1,2]
# res = func()
# print(res)

# def func(x,y):
#     print('111')
#     print('222')
#     print('333')
#     res = x+y
#     return res
# res = func(1,2)
# print(res)

一、函数参数的使用

形参与实参

形参:指的是在定义阶段定义的函数,称之为形式参数,简称形参。

#
# def func(x,y):  # x = 1  y = 2
#     print(x,y)

实参:指的是在调用阶段传入的值,称之为实际参数,简称实参。

# func(1,2)
实参是传入的值,值可以是以下几种形式。
形式一:
# def func(x,y):  # x = 1  y = 2
#     print(x,y)

# func(1,2)
形式二:
# def func(x,y):  # x = 1  y = 2
#     print(x,y)
# a=1
# b=2
# func(a,b)
形式三、
# func(int('1'),2)

# func(func1(1,2),func2(2,3),333)

二、参数详解

2.1 位置参数:按照从左到右的顺序依次定义的参数称之为位置参数

位置形参:****在函数定义阶段按照从左到右的顺序直接定义的'变量名'

特点:必须被传值,多一个不行少一个不行

# def func(x,y):
#     print(x,y)
# func(1,2)
# func(2,1)

位置实参 : 在函数调用阶段,按照从左到右的顺序依次传入的值

特点:按照顺序与形参一一对应

# def func(x,y):
#     print(x,y)
# func(1,2)
# func(2,1)
2.2关键字参数

关键字实参:在函数调用阶段,按照key = value的形式传入的值

特点:指名道姓给某个形参 传值,可以完全不参照顺序、

# def func(x,y):
#     print(x,y)
# func(y=1,x=2)
#
混合使用,强调
# 1、位置实参必须放在关键字实参前
# func(1,y=2)
# func(y=2,1) # 错误示范

# 2、不能为同一个形参重复传值
# func(1,y=2,x=3) # 错误示范
2.3 默认参数

默认形参:

在定义函数阶段,就已经被赋值的形参,称之为默认形参

特点:在定义阶段就已经被赋值的,意味着在调用阶段可以不用为其赋值

def func(x,y=3):
#     print(x,y)
#
# func(x=1)
# func(x=1,y=444) # 也可以继续赋值
位置形参与默认形参混用,强调:
 1、位置形参必须在默认形参的左边
# # def func(1,y=2):
# #     pass
# # 错误示范:
# # def func(y=2,1):
#     pass
# 2、默认参数的值在函数定义阶段就被赋值的,准确的说被赋予的是值的内存地址
# 示范1:
# m = 1
# def func(x,y=m): #y = 2的内存地址
#     print(x,y)
# m=333333
# func(2)

# 示范2:
# m =[1111,]
# def func(x,y=m): #y = [1111]的内存地址
#     print(x,y)
# m.append(2222)
# func(2)

默认形参需要注意的问题

#	1、默认形参的值只在定义阶段被赋值一次
#     2、默认形参的值通常为不可变类型
# 3、虽然默认值可以被指定为任意数据类型,但是不推荐使用可变类型。
# 函数最理想的状态:函数的使用只跟函数本身有关系,不受外界代码的影响

2.4 可变长度的参数(*与**的用法)

# 可变长度指的是在调用函数阶段时,传入的值(实参)的个数不固定
# 而实参是为了给形参赋值的,所以对应着,针对溢出的实参必须有对应的形参来接收

2.4.1可变长度的位置参数

# I:*形参名:用来接收溢出的位置实参,溢出的位置实参会被*保存成元组的格式,
#             然后赋值给紧跟其后的形参名,*后跟的可以是任意名字,但约定俗称应该是args
# def func(x,y,*z):
#     print(x,y,z)
# func(1,2,3,4,5,6)

# def func(*args):
#     res = 0
#     for item in args:
#         res += item
#     return res
#
# res = func(1, 2, 3, 4, 5, 6)
# print(res)

2.4.2可变长度的关键字参数

I:**形参名:用来接收溢出的关键字实参,**会将溢出的关键字实参保存成字典格式,然后赋值给
#             紧跟其后的形参名,**后跟的可以是任意名字,但约定俗称应该是kwargs
# def func(x,y,**kwargs):
#     print(x,y,kwargs)
#
# func(1,y=3,c=4,d=5)

# II:*可以用在实参中,实参中带*,先将*后的值打散成位置实参
# def func(x,y,z):
#     print(x,y,z)
# func(*[11,22,33]) # func(11,22,33)

#III:形参与实参都带*
# def func(x,y,*args):
#     print(x,y,args)
# func(1,2,*[3,4,5])
# func(*'hello')
# II:**可以用在实参中(**后跟的只能是字典),实参中带 **,先将 ** 后的值打散成关键字实参
# def func(x,y,z):
#     print(x,y,z)
# func(*{'x':1,'y':2,'z':3})  # func('x','y','z')
# func(**{'x':1,'y':2,'z':3})  # func(x=1,y=2,z=3)

# III:形参和实参都带**
# def func(x,y,**kwargs):
#     print(x,y,kwargs)
#
# func(**{'x':111,'y':222,'z':333,'d':444})

# 混用*与**:*args必须在**kwargs之前
# def func(*args,**kwargs):
#     print(args,)
#     print(kwargs)
# func(1,2,3,4,a=1,b=2)

# def index(a,b,c):
#     print('index=>>>',a,b,c)
# def wrapper(x,y,z):  # x=1 y=2 z=3
#     index(x,y,z)  # index(1,2,3)
# wrapper(1,2,3)   #为wrapper传的参数是给index用的

-----------------------------------------------函数对象--------------------------------------------

一、函数对象:函数对象指的是函数可以被当做’数据’来处理。

  • 1.1 函数可以被引用
>>> def add(x,y):
...     return x+y
... 
>>> func=add
>>> func(1,2)
3
  • 1.2 函数可以作为容器类型的元素
>>> dic={'add':add,'max':max}
>>> dic
{'add': <function add at 0x100661e18>, 'max': <built-in function max>}
>>> dic['add'](1,2)
3
  • 1.3 函数可以作为参数传入另外一个函数
>>> def foo(x,y,func):
...     return func(x,y)
...
>>> foo(1,2,add)
3
  • 1.4 函数的返回值可以是一个函数
def bar(): 
     return add 
func=bar() 
func(1,2)
3 

二、 闭包函数

2.1 闭与包

基于函数对象的概念,可以将函数返回到任意位置去调用,但作用域的关系是在定义完函数时就已经被确定了的,与函数的调用位置无关。

大前提:

闭包函数= 名称空间作用域+函数嵌套+函数对象

核心点:名字的查找关系是在函数定义阶段为准的

什么是闭包函数?

'闭'函数指的是该函数是内嵌函数

‘包’函数指的是该函数对外层函数作用域名字的引用(不是对全局作用域)

2.2 闭包的用途

目前为止,我们得到了两种为函数体传值的方式,一种是直接将值以参数的形式传入,另外一种就是将值包给函数

闭包函数的这种特性有时又称为惰性计算。使用将值包给函数的方式,在接下来的装饰器中也将大有用处

# 两种为函数体传参的方式:
# 方式一:直接把函数体需要的参数绑定成形参
# def f1(x):
#     print(x)
#
# f1(1)

# 方式二:闭包函数传值
# def f1(x):
#     # x = 33
#     def f2():
#         print(x)
#     return f2  # 把f2传给f1
# f= f1(22)
# print(f)
# f()

# def outter(x):
#     # x = 111
#     def warpper():
#         print(x)
#     return warpper
# f = outter(11)
# print(f)
# f()
posted @ 2021-03-25 20:08  刘较瘦丫  阅读(94)  评论(0编辑  收藏  举报