当前位置: 首页 > article >正文

8.函数定义与使用

一.定义函数

  1. 必备参数
  2. 默认参数
  3. 不定长参数
  4. return返回值
  5. 文本文档
  6. print与return的区别
  7. 其他用法
  8. 传参

二.匿名函数

  1. 基本用法
  2. 单参数函数
  3. 无参数函数
  4. 作为参数传递
  5. 列表推导式
  6. 与函数式编程

三.作用域

  1. 全局变量与局部变量
  2. global()函数
  3. nonlocal()函数

一.定义函数

语法格式:

def 函数名():
        执行语句                     #函数作用
函数名()                              #调用函数
print(函数名)                      #输出函数名的储存代码,内存地址

参数分为:
1.形式参数(形参):定义函数时的输入参数,没有具体的数据   如a,b
2.实际参数(实参):调用函数时传递的参数,有具体的数据      如调用函数时的括号内的数据

就如剧本中,角色相当于形参,而演员相当于实参


定义函数时,函数名(形参1,形参2,形参3,....) ,
定义函数式为形参,调用函数时是实参

必备参数:形参有几个实参必须有几个
默认参数:在定义形参是给形参传递的数据.可被后续实参所替换,常与必备参数连用
不定长参数1:*args 将数据装包到一个元组中
不定长参数2:**kwargs 将数据封包到一个字典中

1.必备参数

必备参数:形参与实参一一对应,实参可以少于形参,但不能多于形参

就相当于演员(实参)数量多于角色(形参)数量了这样不行,但是角色(实参)数量小于角色(形参)数量这样可以

一一对应:形参a,b的顺序与调用函数时的实参顺序一致,既a:对应李二牛,b:对应翠花,执行语句中所有形参a的位置会在调用函数时变为"李二牛",执行语句中所有形参b会在调用函数时变为"翠花".

def name(a,b):  
    print(f'我是{a}')
    print('她是{}'.format(b))
#在调用函数之前,上面出现的a,b就是形参
name('李二牛','翠花')   #调用函数,这里的"李二牛","翠花"是实参

2.默认参数       

默认函数既在定义函数时,在形参位置上对其进行提前赋值,但是此赋值可以在调用函数时对其进行覆盖,且赋值只能从右往左依次赋值,既保持(形参,形参,形参,形参=xx,形参=xxx)的样子,不能出现(形参=xx,形参,形参=xxx)此类情况.

此案例中,第一次调用number函数时参数a,b,c对应的实参分别为1,2,3.虽然在定义函数时c=5,但是调用函数时会对原参数值进行覆盖

第二次调用number函数时参数a,b,c只有a,b有对应的实参,所以c会默认为定义函数时的值5

def number(a,b,c=5):
    print(a,b,c)
number(1,2,3)  
number(1,2)
1 2 3
1 2 5

3.不定长参数

在使用时,先使用必备参数,默认参数,再使用不定长参数1,不定长参数2

1.不定长参数1

在形参前面加一个*号可以接受任意数据,并且将所有的实参装包到一个元组中

在第一次调用f函数时,由于没有实参,所以在跑代码时,第一个print会输出(),类型为元组

def f(*args):
    print(args)
    print(type(args))
print("第一次调用:")
f()
print("第二次调用:")
f(123,45)
第一次调用:
()
<class 'tuple'>
第二次调用:
(123, 45)
<class 'tuple'>

2.不定长参数2

在形参前加两个**,可以将任意数据保存到字典中,键就是参数的名字,字典里的值就是参数值

def grand(a, b, c, **kwargs):
    print(f'''{a}年
{b}岁 
{c}年纪
{kwargs}tam
''')
grand(1, 2, 3, java=2, python=34)
1年
2岁 
3年纪
{'java': 2, 'python': 34}tam

1.1小节:

def wish(a,b,c,d=3,*args,**kwargs):
    print(f'''
    我是{a}
    我希望{b}
    并且{c}
    不挂{d}课
    他们是{args}
    还可能是{kwargs}
    ''')
wish('大学生','不挂科','不重修',4,'高代','数分','英语',Java=20,Python=100)

    我是大学生
    我希望不挂科
    并且不重修
    不挂4课
    他们是('高代', '数分', '英语')
    还可能是{'Java': 20, 'Python': 100}

4.返回值return

在此案例中,先使用f(5),进行调用函数,输出print语句,return语句不会输出返回值.a=f相当于将f函数的内容复制一份给a,使a具有与f相同的功能,print(a(5))与print(f(5))效果是一样的,因为函数功能是一样的,既会调用函数,也会输出return语句的返回值.

def f(x):
    print(x+2)
    return x + 1
f(5)         #调用函数
a = f        #将函数的整体赋值给变量,换名字
a(4)
print(a(5))  #调用函数并输出函数的返回值
print(f(5))  #原名称的函数依然可用
7
6
7
6
7
6

 一个函数只能有一个return语句,且return语句后面不能有任何代码了,有了也不会执行

def f(x):
    print(x+2)
    return x + 1
    print("不会执行")
    return "不会执行"
f(4)
6

 5.文本文档

语法格式:函数名.__doc__

 既可以输出定义函数内的文本注释,既使用"""三引号括起来的部分

def a(a,b):
    '''输出两数相乘'''
    return a*b
print(a.__doc__)#输出函数内部的文本文档
print(a(3,3))
输出两数相乘
9

6.print与return的区别

return:将return后的语句作为返回值,返回给函数

print:在调用函数时,会将定义的函数跑一遍,在跑的过程中就可以将print语句输出出来

该例子中

  1. b=num1():由于num1是将12,3,356,7,8,True这些值返回给num1,所以在该赋值语句中,b变量的值会等于12,3,356,7,8,True
  2. print(b):用于输出b的值
  3. b1,b2,*b3=num1():表示b1,b2分别接收num1()返回值的前两个,*b3表示剩下的返回值由b3接收
  4. a=num2():表示将函数num2()的功能复制给a一份
  5. a():表示调用函数a,既调用函数num2(),由于是调用并没有print语句用来输出num2()的返回值,所以return "num2()函数"不会输出
  6. 当函数没有返回值时,使用print语句会输出None
def num1():
    return 12,3,356,7,8,True
def num2():
    print(468)
    return "num2()函数"
b = num1()   #return 出来的是一个值,加括号表示将函数返回值赋值,先调用再输出
print(b)    #等效于print(num1())
b1,b2,*b3 = num1()
print(b1)
print(b2)
print(b3)

a= num2  #赋值时是赋值函数名,print出来的是函数,使用时还需要调用函数
a()
(12, 3, 356, 7, 8, True)
12
3
[356, 7, 8, True]
468

 由于num1为函数名,所以类型为function

返回值为12,2,True,所以为元组tuple类型

def num1():
    return 12,2,True
print(type(num1))
print(type(num1()))
<class 'function'>
<class 'tuple'>

7.其他用法

def num1():
    print('你好')
    return 12
print(num1)  #输出函数的地址
set1=[1,2,True,num1]
print(set1[3]())  #等于print(num1())调用函数并返回函数返回值
set1[3]()

def name(a,b):
    return a+b
name1 =(66,88,99,name)
print(name1[3](5,6))

def nun(a,b):
    return a+b
name2 =(20,30,40,nun(3,4))
print(name2[3])

def name():
    my_name = '毛毛'
    return my_name
def me (a):
    print(f'{a}是好人')
me(name())
<function num1 at 0x00000258AAF93F40>
你好
12
你好

11

7

毛毛是好人

8.传参

定义的函数只有在调用时才会发挥作用,与其所在位置无关!

在调用boss1(1,2)函数时,由于定义函数boss1(a,b)所以a=1,b=2,boss1的返回值return函数返回的应该是boss2(2,1),调用函数时应print(boss2(1,2))

因为boss1的参数是a,b,所以a和b会作为参数按顺序传递到boss2(c,d)既c=a,d=b

print(boss1(1,2))会先调用函数,再输出boss1的返回值

def boss1(a,b):
    def boss2 (c,d):
        return c+d*10    
    print(boss2(a,b))
    return boss2(b,a)    

print(boss1(1,2))

 上方代码等效于:

def boss1(a,b):
    def boss2 (c,d):
        return c+d*10    
    print(boss2(1,2))
    return boss2(2,1)    

print(boss1(1,2))
21
12

二.匿名函数

语法格式:lambda 变量:操作

print(lambda a,b :a+b)地址
print(lambda a,b :a+b(4,5)) 自带返回值内容

1.不取名字(不用def)
2.函数只用一次的情况下 可以使用匿名函数

匿名函数不会给程序带来运行效率的提高只是使代码更加简洁,匿名函数是为了减少单行定义函数而存在

1.基本用法

lambda函数可以接受任意数量的参数,但只能有一个表达式。

# 定义一个匿名函数,计算两个数的和
add = lambda x, y: x + y

# 使用匿名函数
print(add(3, 4))  
7

2.单参数函数

如果lambda函数只有一个参数,可以省略参数名。

# 定义一个匿名函数,计算数字的平方
square = lambda x: x * x

# 使用匿名函数
print(square(5)) 
25

3.无参数函数

lambda函数也可以不接受任何参数。

# 定义一个匿名函数,返回固定的字符串
greet = lambda: "Hello, World!"

# 使用匿名函数
print(greet())  
Hello, World!

4.作为参数传递

lambda函数经常作为参数传递给函数,特别是在使用高阶函数时。

# 使用lambda函数作为参数传递给sorted函数
numbers = [5, 2, 9, 1, 5, 6]
sorted_numbers = sorted(numbers, key=lambda x: x)
print(sorted_numbers) 
[1, 2, 5, 5, 6, 9]

5.列表推导式

lambda函数可以在列表推导式中使用。

# 使用lambda函数在列表推导式中创建一个新列表
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)  
[1, 4, 9, 16, 25]

6.与函数式编程

lambda函数可以与Python的内置函数如map(), filter(), reduce()等结合使用,实现函数式编程风格。

# 使用lambda函数和map函数
numbers = [1, 2, 3, 4, 5]
doubled = list(map(lambda x: x * 2, numbers))
print(doubled) 

# 使用lambda函数和filter函数
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)  
[2, 4, 6, 8, 10]
[2, 4]

三.作用域

名称空间
1.内键名称空间(内置函数):
    生命周期:随着Python文件的启动而生成程序关闭时 清除数据,
    加载顺序:第一
    存放对象:内置函数,print ,input
2.全局名称空间(定义在函数外层的名字)
    生命周期:随着Python文件执行之前产生,运行后收回
    加载顺序:第二
    存放对象:在Python外层写的代码,如定义的函数名,定义的变量名
3.局部名称空间(存在函数内部定义的名字)
    生命周期:随着函数调用而生成
    加载顺序:第三,调用函数时才会执行
    存放对象:在函数内定义的变量名或函数形参
变量:

  1. 只能包括字母,数字,下划线
  2. 只能以字母和下划线为首
  3. 不要使用关键字为变量量名

1.全局变量与局部变量

案例1:

total=0
def f(a,b):
    total=a+b
    print("此处的total为局部变量=",total)
f(1,2)
print("此处的total为局部变量=",total)
此处的total为局部变量= 3
此处的total为局部变量= 0

案例2:

a=10
def function(a):
    b=1
    a=a+b #此处形参a为局部变量,不会对外部的a=10作出改变
    print("此处b和a均为局部变量,a=",a)
function(a)#此处传入的实参a为全局变量10
print(a) #输出全局变量a=10,不受局部变量a=a+b的改变
此处b和a均为局部变量,a= 11
10

2.global()函数

在案例2中,对function内部的局部变量a的操作不影响全局变量a=10.若想对全局变量a产生影响,可以使用global()函数,但是形参不可以与要使用global的变量一致,既不能使用global  a

那么若想对局部变量,受定义函数内部的影响,就需要将a改个名字,这里将function(a)的形参改为function(c)

注意:需要先调用函数,才能对局部变量产生影响,不然就会像第一个print(a)一样,输出结果为10

a=10
def function(c):
    global a
    b=1
    a=a+b #此时a会对外部的a=10作出改变
    print("此处b和a均为局部变量,a=",a)
print(a)
function(a)#此处传入的实参a为全局变量10
print(a) #输出全局变量a=10,不受局部变量a=a+b的改变
10
此处b和a均为局部变量,a= 11
11

3.nonlocal()函数

print('nonlocal的方法:')
b='世界'
def fun():
    b=1             #在这个fun()函数内b相对于函数fun1()是全局变量
    def fun1():     #使用此方法对b=1进行修改
        nonlocal b
        b = '你好'
    fun1()          #修改后调用此函数,进行调用
    print(b)
fun()
print(b)
你好
世界

如果是使用global函数怎会对最外侧的b="世界"进行修改


b='世界'
def fun():
    b=1             #在这个fun()函数内b相对于函数fun1()是全局变量
    def fun1():     #使用此方法对b=1进行修改
        global b
        b = '你好'
    fun1()          #修改后调用此函数,进行调用
    print(b)
fun()
print(b)
1
你好


http://www.kler.cn/news/360142.html

相关文章:

  • vue开发环境,生产环境实现跨域请求使用nginx
  • 多IP访问多网段实验
  • Git的原理和使用(四)
  • Redis如何批量删除指定前缀的key
  • 88.【C语言】文件操作(5)
  • php计算经纬度距离 及 某点是否在经纬度节点范围
  • apache flink+starrack+paino 打造流批一体数据仓库
  • 【HeadFirst 设计模式】适配器模式的C++实现
  • XS2123--------IEEE 802.3af 兼容的 PD 和 DC/DC 控制器集成功率 MOSFET V2.0
  • 找不到包的老版本???scikit-learn,numpy,scipy等等!!
  • 【Golang】Go语言web框架Gin响应客户端有哪些方式
  • C++详细笔记(四)
  • 每日OJ题_牛客_集合_排序_C++_Java
  • stable diffusion WEBUI Brief summary
  • 家政小程序搭建,数字化市场发展下的意义
  • RK3588开发笔记-麦克风阵列多pdm通道合并成一个声卡
  • 智能新势力:防爆挂轨巡检机器人助力化工安全
  • 外包干了2个月,技术明显退步
  • Java八股整合(Kafka+RocketMQ+K8S)
  • Redis入门:在Java程序中高效使用Redis