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

4.Python基础之函数

文章目录

  • Python基础之函数
    • 函数的作用
    • 函数名的命名规则
    • 函数的定义
      • 1.基本格式
      • 2.带有参数的格式:
      • 3.带有默认值的参数的格式:
      • 4.使用关键字参数格式:
      • 5.收集参数使用方法:
    • 函数的返回值
    • 递归函数
    • 函数文档的使用
    • 变量的作用域
      • global关键字
    • 内部函数
    • 闭包
      • Python闭包的\__closure__属性
    • nonlocal
    • lambda表达式

Python基础之函数

在计算机中称之为函数,在现实生活中称之为功能。 函数是能够实现特定功能的计算机代码,它是一种特定的代码组结构

函数的作用

1.提高代码的重复利用率,避免重复开发相同代码

2.提高程序的开发效率

3.便于程序维护

函数名的命名规则

1.推荐使用英文,禁止使用中文

2.可以使用数字,但不能以数字开头

3.不可以使用特殊字符,除了下划线_

4.函数名严格区分大小写

5.函数名必须要有意义

6.不能和系统保留关键字冲突

函数的定义

1.基本格式

def 函数名():
    pass

示例:

#定义函数
def funName():
    pass #此处编写功能代码

funName() #调用

'''注释:
函数的特征:函数定义之后,不会自动执行,只会在调用的时候执行。不调用,不执行。
'''

2.带有参数的格式:

def 函数名(参数1,参数2...):
    pass

示例:

#定义带有参数的函数
def funName(arg):
    print('接收到的参数:',arg)

funName(666) #调用

'''注释:
形参:形式上的参数,声明函数时,括号()中的参数,是形参。
实参:实际上的参数,调用函数是,括号()中的参数,是实参。
实参将值传递给形参的本质过程,本质上就是简单的变量赋值。
'''

3.带有默认值的参数的格式:

def 函数名(参数1 =1,参数2 =2...):
    pass

示例:

#定义带有默认值参数的函数
def funName(arg = 'jack'):
    print('参数值:',arg)

funName() #调用方式一
funName('mark') #调用方式二  调用时传的参数会覆盖默认值

'''注释:
如果形参有默认值,调用时可以不需要传参,系统会直接使用参数的默认值。
调用时给有默认值的参数传参,实参会覆盖形参的默认值。本质上就是变量的重新赋值。
'''

4.使用关键字参数格式:

函数名(形参1 = 实参1,形参2 = 实参2...)

示例:

#定义带有默认值参数的函数
def funName(name = 'jack',age = 18,sex = 'man'):
print('name:',name)
print('age:',age)
print('sex:',sex)

funName(8,'二狗','Superman') #参数较多时赋值顺序颠倒,将会影响程序执行结果
funName(age = 8,name = '二狗',sex = 'Superman') #关键字参数赋值完美解决上面的问题

'''注释:
关键字参数就是调用函数时,在实参前面指定形参的做法,为了防止参数按照位置传递出现的错误。
'''

5.收集参数使用方法:

收集参数可以收集的参数不受数量限制

1)非关键字收集参数

def 函数名(*参数名):
    pass

示例:

#定义带有非关键字收集参数的函数
def funName(*arg):
    for v in arg: #遍历
        print(v)

funName(1,2,3,'a','b','c') #调用

'''注释:
1.非关键字收集参数,在形参前添加一个*即可
2.非关键字收集参数,收集的实参会组成一个元组
3.非关键字收集参数,接受没有任何形参接受的非关键字实参
4.非关键字收集参数,可以和普通的形参共存
'''

2)关键字收集参数

def 函数名(**参数名):
    pass

示例:

#定义带有关键字收集参数的函数
def funName(**car):
    for v in car: #遍历
        print(v,'value : ',car[v])

funName(a = '卡车',b = '火车',c = '公交车') #调用

'''注释:
1.关键字收集参数,在形参前添加两个*
2.关键字收集参数,收集的实参会组成一个字典,形参名作为键,值作为值
3.关键字收集参数,仅接收没有任何形参接收的关键字参数
4.关键字收集参数,可以和普通的形参共存
'''

多种参数混合使用应当注意的 定义函数时尽量避免多种参数格式混合(普通参数,关键字参数,两种收集参数) 1.普通参数和关键字参数必须在两种收集参数之前 2.非关键字收集参数,必须在关键字收集参数之前 3.如果多种参数混合在一起用,必须注意禁止参数多次赋值操作(普通参数赋值在前,关键字参数赋值在后)

函数的返回值

根据执行函数完毕是否可以得到一个结果,我们可以将函数分为两种类型。

执行过程函数:
    函数执行完毕之后,接收不到任何返回结果的函数。如:print()

具有返回值得函数:
    函数执行完毕之后,会产生一个结果,可以被接收和使用的函数。如:type()

格式:

def 函数名(参数...):
    Python code...
    return 返回值 #有return的函数,就是有返回值的函数

变量名 = 函数名(参数...)  #我们可以通过一个变量去接收函数的返回值

'''注释:
1.具有return语句的函数,我们称之为具有返回值的函数
2.return可以为当前函数执行完毕的函数返回一个结果,这个返回值可以用变量接收
3.return执行之后,函数将会终止,所以return之后的语句是不会被执行的
4.一个函数可以使用多个return语句,但是只有一个会被执行,一般都是放入分支结构中
5.一个函数如果需要返回多个数据,使用复合数据类型(list,tuple,set,dict)来操作即可
'''

递归函数


在函数内调用当前函数本身的函数就是递归函数

定义递归函数

#定义一个递归函数
def tubie(num):
    #1.输出num
    print(num)
    #2.判断条件,不改变num
    if num >0:
        tubie(num-1)
    else:
        print('================')
    #3.输出num
    print(num)
#调用递归函数
tubie(3)
----------------------------------------------------------------------
3
2
1
0
================
0
1
2
3

函数文档的使用

函数文档就是用来查看当前函数相关信息介绍的一个特定格式而已。

查看函数文档的方法:

help(函数名)
    此方法会直接输出函数文档的内容

函数名.__doc__
    直接输出显示函数文档的内容元字符串(可以使用print(函数名.__doc__)来解决无格式问题)

-------------------------------------------------------------
help(print)
print(print.__doc__)

Help on built-in function print in module builtins:

print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.


定义函数文档的方法:

def 函数名(参数):
    '''
    这里编写函数文档
    '''

    这里编写函数的code...

示例:

#定义函数文档的方式
def funName(**car):
    '''
    这里是函数文档
    本函数功能是...
    要求的参数类型是...
    返回的数据是...
    '''

    print('函数文档的定义方法')

help(funName)
 #查看函数文档

'''注释:
函数文档的作用是对函数进行说明,便于阅读和快速掌握函数的使用,通常函数文档需要具有以下信息:
1.函数的作用
2.函数的参数介绍(需要几个参数,分别是什么类型)
3.函数的返回值(数据和类型)
'''

变量的作用域

变量的作用域就是指变量的有效范围。

变量按照作用范围分为两类,分别是 全局变量局部变量

**全局变量:**在函数外部声明的变量就是全局变量

有效范围:
    全局变量在函数外部可以正常使用。
    全局变量在函数内部也可以正常使用(需要用global声明)

**局部变量:**在函数内部声明的变量就是局部变量

有效范围:
    局部变量在函数内部可以正常使用
    局部变量在函数外部不可以访问

global关键字

global的作用就是把局部变量提升为全局变量

格式:

def 函数名():
    global 变量名
    函数功能代码...

示例:

def funName():
    global name #如果不使用global关键字,外部是无法访问变量name的。
    name = 'dragon'

funName()  #调用

print(name)  #尝试访问内部函数

'''注释:
global只有在函数内部对变量进行全局声明,该变量才是一个完整的全局变量(在函数外部可以对该变量进行任意操作)。
'''

内部函数

在函数内部声明的函数就是内部函数。

格式:

def 函数名():
    局部变量...
    def 内部函数名():
        Python功能代码...

示例:

def funName():
    name = 'dragon'
    #定义一个内部函数
    def inner():
        print('我是内部函数')

'''注释:
    1.内部函数的本质就是局部变量(函数就是一个变量)
    2.内部函数在函数外部不可以直接调用
    3.内部函数在函数内部调用(当然,必须要定义内部函数之后才能调用)
'''

闭包

使用特定或特殊的方式,将局部变量(内部函数)引入到全局环境中使用,这就是闭包操作。

闭包,又称闭包函数或者闭合函数,其实和前面讲的嵌套函数类似,不同之处在于,闭包中外部函数返回的不是一个具体的值,而是一个函数。一般情况下,返回的函数会赋值给一个变量,这个变量可以在后面被继续执行调用。

闭包方法1:

def 函数名():
    局部变量...
    def 内部函数名():
        pass
    return (局部变量,内部函数...)

闭包方法2:

def 函数名():
    局部变量
    def 内部函数名():
        pass
    #获取所有需要进行闭包操作的函数和变量
    defall():
        return(局部变量,内部函数...)
    return all

闭包原理:

#闭包函数,其中 exponent 称为自由变量
def nth_power(exponent):
    def exponent_of(base):
        return base ** exponent
    return exponent_of # 返回值是 exponent_of 函数
square = nth_power(2) # 计算一个数的平方
cube = nth_power(3) # 计算一个数的立方

print(square(2))  # 计算 2 的平方
print(cube(2)) # 计算 2 的立方

4
8

在上面程序中,外部函数 nth_power() 的返回值是函数 exponent_of(),而不是一个具体的数值。需要注意的是,在执行完 square = nth_power(2) 和 cube = nth_power(3) 后,外部函数 nth_power() 的参数 exponent 会和内部函数 exponent_of 一起赋值给 squre 和 cube,这样在之后调用 square(2) 或者 cube(2) 时,程序就能顺利地输出结果,而不会报错说参数 exponent 没有定义。

看到这里,读者可能会问,为什么要闭包呢?上面的程序,完全可以写成下面的形式:

def nth_power_rewrite(base, exponent):
    return base ** exponent
    
# 不使用闭包
res1 = nth_power_rewrite(base1, 2)
res2 = nth_power_rewrite(base2, 2)
res3 = nth_power_rewrite(base3, 2)
# 使用闭包
square = nth_power(2)
res1 = square(base1)
res2 = square(base2)
res3 = square(base3)

显然第二种方式表达更为简洁,在每次调用函数时,都可以少输入一个参数。其次,和缩减嵌套函数的优点类似,函数开头需要做一些额外工作,当需要多次调用该函数时,如果将那些额外工作的代码放在外部函数,就可以减少多次调用导致的不必要开销,提高程序的运行效率。

Python闭包的__closure__属性

闭包比普通的函数多了一个 closure 属性,该属性记录着自由变量的地址。当闭包被调用时,系统就会根据该地址找到对应的自由变量,完成整体的函数调用。

以 nth_power() 为例,当其被调用时,可以通过 closure 属性获取自由变量(也就是程序中的 exponent 参数)存储的地址,例如:

    def nth_power(exponent):
        def exponent_of(base):
            return base ** exponent
        return exponent_of
    square = nth_power(2)
    #查看 __closure__ 的值
    print(square.__closure__)
    
    输出:(<cell at 0x0000014454DFA948: int object at 0x00000000513CC6D0>,)

可以看到,显示的内容是一个 int 整数类型,这就是 square 中自由变量 exponent 的初始值。还可以看到,closure 属性的类型是一个元组,这表明闭包可以支持多个自由变量的形式。

闭包的优缺点:

优点:
    1.可以方便的进行函数式编程,组织程序代码
    2.使内部函数和局部变量在外部可以访问

缺点:
    1.闭包操作会导致整个函数的内部环境,被长久保存,占用大量内存。

闭包环境查看:closure

用于查询当前闭包操作所使用的环境中的变量和内部函数等信息。

nonlocal

nonlocal关键字的意义,不是局部变量,当然他也不是全局变量,通常用于内部函数中使用外部函数的局部变量。

#声明一个外部函数
def outer():
    #声明一个变量(肯定不是全局变量)
    x = 5
    #声明一个内部函数
    def inner():
        nonlocal x  #声明x不是局部变量
        x += 9
        print(x)
    #调用函数
    inner()
#调用outer
outer()

'''注释:
如果内部函数想使用全局变量,那么应该使用global声明变量
(函数最外层的全局变量)
如果内部函数使用的是外部函数的局部变量,那么应该使用nonlocal声明
(内部函数的外层,外部函数的局部变量)
'''

lambda表达式

lambda表达式是一种简洁格式的函数。该表达式不是正常的函数结构,而是属于表达式的类型。

基本格式:

lambda 参数,参数...:函数功能代码
如:lambda x,y:x + y    获取2个值的和的lambda函数

带分支格式:

lambda 参数,参数... :值1  if 条件表达式  else 值2
如:lambda sex : '有胡子' if sex == 'man' else '没胡子'

调用函数格式:

lambda 参数,参数...:其他函数(...)
如:lambda x:type(x)

lambda表达式的优缺点:

优点:
    书写简单不需要def关键字
    不需要费脑子想函数名(匿名函数)看起来高大上!

缺点:
    lambda表达式功能受限,无法使用循环和多项分支
    复杂的操作,不适合lambda表达式

示例

#方式1.声明一个简单的lambda表达式
mylamb = lambda x,y:x+y
#调用函数
result = mylamb(4,5)
print(result)

#方式2.声明一个带有分支的lambda表达式
mylamb= lambda sex : '有胡子' if sex == 'man' else '没胡子'
#调用函数
result = mylamb('woman')
print(result)

#方式3.声明一个调用函数的lambda表达式
mylamb = lambda x:type(x)
#调用函数
result = mylamb('拾元')
print(result)

相关文章:

  • wordpress 剪切板图片自动上传/如何让新网站被收录
  • 教育网站建设计划书/网络营销公司业务范围
  • 中国房地产信息网官网/汕头网站建设方案优化
  • 合肥网站建设费用/公众号关键词排名优化
  • 移动端网站开发教案/中文搜索引擎大全
  • 做内衣的网站好/官网seo是什么意思
  • PicGo+Gitee+Typora实现markdown图床
  • Ajax基础
  • 【Linux 基础】
  • NEUQ week11题解
  • 【华为OD机试真题2023 JAVA】查找树中元素
  • (小甲鱼python)函数笔记合集三 函数(III)总结 函数的收集参数*args **args 解包参数详解
  • Tomcat 三种简单网站部署方式
  • 【蓝桥杯】历届真题 双向排序(省赛)Java
  • SpringBoot项目练习
  • VueUse(中文)——简介
  • python学习笔记---Python基础【廖雪峰】
  • 架构设计导论