python函数

概述

定义一个函数
你可以定义一个由自己想要功能的函数,以下是简单的规则:

函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
函数内容以冒号 : 起始,并且缩进。
return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。

在这里插入图片描述

def 函数名(参数列表):
    函数体

定义一个简单函数

def fn() :
    print('这是我的第一个函数!')
    print('hello')
    print('今天天气真不错!')

调用函数

fn()

在这里插入图片描述

函数传参

# 求任意三个数的乘积
def mul(a,b,c):
    print(a*b*c)
# 调用
mul(1,2,3)

在这里插入图片描述

# 根据不同的用户名显示不同的欢迎信息   
def welcome(username):
    print('欢迎',username,'光临')
# 调用
welcome('孙悟空')

在这里插入图片描述

为函数参数设置默认值

# 定义一个函数
# 定义形参时,可以为形参指定默认值
# 指定了默认值以后,如果用户传递了参数则默认值没有任何作用
#   如果用户没有传递,则默认值就会生效
def fn(a = 5 , b = 10 , c = 20):
    print('a =',a)
    print('b =',b)
    print('c =',c)
# 调用
fn(1 , 2 , 3)
fn(1 , 2)
fn()

在这里插入图片描述

实参的传递方式

# 位置参数
# 位置参数就是将对应位置的实参复制给对应位置的形参
# 第一个实参赋值给第一个形参,第二个实参赋值给第二个形参 。。。
fn(1 , 2 , 3)

在这里插入图片描述

关键字参数

# 关键字参数,可以不按照形参定义的顺序去传递,而直接根据参数名去传递参数
fn(b=1 , c=2 , a=3)

在这里插入图片描述

def fn4(a):
    # 在函数中对形参进行重新赋值,不会影响其他的变量
    # a = 20
    # a是一个列表,尝试修改列表中的元素
    # 如果形参执行的是一个对象,当我们通过形参去修改对象时
    #   会影响到所有指向该对象的变量
    a[0] = 30
    print('a =',a,id(a))

c = 10
c = [1,2,3] 
fn4(c)
fn4(c.copy())
fn4(c[:])

在这里插入图片描述

不定长的参数

# 定义一个函数,可以求任意个数字的和
def sum(*nums):
    # 定义一个变量,来保存结果
    result = 0
    # 遍历元组,并将元组中的数进行累加
    for n in nums :
        result += n
    print(result)
# 调用函数
sum(123,456,789,10,20,30,40)
sum(123,456)

在这里插入图片描述

# 在定义函数时,可以在形参前边加上一个*,这样这个形参将会获取到所有的实参
# 它将会将所有的实参保存到一个元组中
# a,b,*c = (1,2,3,4,5,6)
# *a会接受所有的位置实参,并且会将这些实参统一保存到一个元组中(装包)
def fn(*a):
    print("a =",a,type(a))
# 调用
fn(1,2,3,4,5)

在这里插入图片描述

带星号的形参只能有一个
带星号的参数,可以和其他参数配合使用

# 第一个参数给a,第二个参数给b,剩下的都保存到c的元组中
def fn2(a, b, *c):
    print('a =', a)
    print('b =', b)
    print('c =', c)


# 调用函数
fn2(2, 3, 4, 5, 6)

在这里插入图片描述

可变参数不是必须写在最后,但是注意,带*的参数后的所有参数,必须以关键字参数的形式传递

# 可变参数不是必须写在最后,但是注意,带*的参数后的所有参数,必须以关键字参数的形式传递
# 第一个参数给a,剩下的位置参数给b的元组,c必须使用关键字参数
def fn2(a, *b, c):
    print('a =', a)
    print('b =', b)
    print('c =', c)


fn2(1, 2, 3, 4, c=2)


# 所有的位置参数都给a,b和c必须使用关键字参数
print("第一个参数有*")
def fn2(*a, b, c):
    print('a =', a)
    print('b =', b)
    print('c =', c)

fn2(1, 2, 3, b=2, c=1)


# 如果在形参的开头直接写一个*,则要求我们的所有的参数必须以关键字参数的形式传递
print("形参的开头直接写一个*")
def fn2(*, a, b, c):
    print('a =', a)
    print('b =', b)
    print('c =', c)


fn2(a=3,b=4,c=5)

print("**形参")
# **形参可以接收其他的关键字参数,它会将这些参数统一保存到一个字典中
#   字典的key就是参数的名字,字典的value就是参数的值
# **形参只能有一个,并且必须写在所有参数的最后
def fn3(b, c, **a):
    print('a =', a, type(a))
    print('b =', b)
    print('c =', c)


fn3(b=1,d=2,c=3,e=10,f=20)

在这里插入图片描述

参数的解包(拆包)

def fn4(a, b, c):
    print('a =', a)
    print('b =', b)
    print('c =', c)


# 创建一个元组
t = (10, 20, 30)

# 传递实参时,也可以在序列类型的参数前添加星号,这样他会自动将序列中的元素依次作为参数传递
# 这里要求序列中元素的个数必须和形参的个数的一致
fn4(*t)

# 创建一个字典
d = {'a': 100, 'b': 200, 'c': 300}
# 通过 **来对一个字典进行解包操作
fn4(**d)

在这里插入图片描述

返回值

返回值就是函数执行以后返回的结果
可以通过 return 来指定函数的返回值
可以之间使用函数的返回值,也可以通过一个变量来接收函数的返回值

def sum(*nums):
    # 定义一个变量,来保存结果
    result = 0
    # 遍历元组,并将元组中的数进行累加
    for n in nums:
        result += n
    return result


print(sum(123, 456, 789))

在这里插入图片描述

return 后边跟什么值,函数就会返回什么值,return 后边可以跟任意的对象,返回值甚至可以是一个函数

def fn():
    # return 'Hello'
    # return [1,2,3]
    # return {'k':'v'}
    def fn2():
        print('hello')

    return fn2  # 返回值也可以是一个函数


r = fn()  # 这个函数的执行结果就是它的返回值


# r()
print(fn())
print(r)

在这里插入图片描述

如果仅仅写一个return 或者 不写return,则相当于return None

def fn2():
    a = 10
    return

print(fn2())

在这里插入图片描述

在函数中,return后的代码都不会执行,return 一旦执行函数自动结束

def fn3():
    print('hello')
    return
    print('abc')


r = fn3()
print(r)

在这里插入图片描述

def fn4():
    for i in range(5):
        if i == 3:
            # break 用来退出当前循环
            # continue 用来跳过当次循环
            return  # return 用来结束函数
        print(i)
    print('循环执行完毕!')


fn4()

在这里插入图片描述

fn5 和 fn5()的区别

def fn5():
    return 10

print(fn5)  # fn5是函数对象,打印fn5实际是在打印函数对象 <function fn5 at 0x05771BB8>
print(fn5())  # fn5()是在调用函数,打印fn5()实际上是在打印fn5()函数的返回值 10

在这里插入图片描述

文档字符串

# help()是Python中的内置函数
# 通过help()函数可以查询python中的函数的用法
# 语法:help(函数对象)
# help(print) # 获取print()函数的使用说明

# 文档字符串(doc str)


# 在定义函数时,可以在函数内部编写文档字符串,文档字符串就是函数的说明
#   当我们编写了文档字符串时,就可以通过help()函数来查看函数的说明
#   文档字符串非常简单,其实直接在函数的第一行写一个字符串就是文档字符串
def fn(a: int, b: bool, c: str = 'hello') -> int:
    '''
    这是一个文档字符串的示例

    函数的作用:。。。。。
    函数的参数:
        a,作用,类型,默认值。。。。
        b,作用,类型,默认值。。。。
        c,作用,类型,默认值。。。。
    '''
    return 10


help(fn)

在这里插入图片描述

作用域

作用域指的是变量生效的区域

def fn():
    a = 10 # a定义在了函数内部,所以他的作用域就是函数内部,函数外部无法访问
    print('函数内部:','a =',a)
    print('函数内部:','b =',b)

fn()

在这里插入图片描述

高阶函数

只要满足下面的任意一个条件就是高阶函数

1、一个函数的函数名作为参数传给另外一个函数
2、一个函数返回值(return)为另外一个函数(返回为自己,则为递归)

高阶函数:一个函数的函数名作为参数传给另外一个函数

def func():
    print("定义一个普通函数")


def high_level(func):
    print("定义一个高阶函数")
    # 在函数内部,通过传入的函数参数调用
    func()


high_level(func)

在这里插入图片描述

高阶函数:一个函数返回值(return)为另外一个函数

def func():
    print("定义一个普通函数")


def high_level(func):
    print("定义一个高阶函数")
    return func
    #  return func() 这个是直接返回函数调用,递归函数就是如此


res = high_level(func)
# 高阶函数返回函数之后在调用func函数
res()
# 结果

在这里插入图片描述

闭包

将函数作为返回值返回,也是一种高阶函数
这种高阶函数我们也称为叫做闭包,通过闭包可以创建一些只有当前函数能访问的变量
可以将一些私有的数据藏到的闭包中

def fn():

    a = 10

    # 函数内部再定义一个函数
    def inner():
        print('我是fn2' , a)

    # 将内部函数 inner作为返回值返回   
    return inner

# r是一个函数,是调用fn()后返回的函数
# 这个函数实在fn()内部定义,并不是全局函数
# 所以这个函数总是能访问到fn()函数内的变量
a=100
r = fn()    

r()

形成闭包的要件

① 函数嵌套
② 将内部函数作为返回值返回
③ 内部函数必须要使用到外部函数的变量

def make_averager():
    # 创建一个列表,用来保存数值
    nums = []

    # 创建一个函数,用来计算平均值
    def averager(n) :
        # 将n添加到列表中
        nums.append(n)
        # 求平均值
        return sum(nums)/len(nums)

    return averager

averager = make_averager()

print(averager(10))
print(averager(20))
print(averager(30))
print(averager(40))

在这里插入图片描述

装饰器

相当于高阶函数,根据现有的函数,来创建一个新的函数

希望函数可以在计算前,打印开始计算,计算结束后打印计算完毕
我们可以直接通过修改函数中的代码来完成这个需求,但是会产生以下一些问题
① 如果要修改的函数过多,修改起来会比较麻烦
② 并且不方便后期的维护
③ 并且这样做会违反开闭原则(OCP)
程序的设计,要求开发对程序的扩展,要关闭对程序的修改

def add(a , b):
    '''
        求任意两个数的和
    '''
    r = a + b
    return r

# 只需要根据现有的函数,来创建一个新的函数
def fn2(a, b):
    print('函数开始执行~~~')
    print(add(a, b))
    print('函数执行结束~~~')

在这里插入图片描述

def new_add(a, b):
    print('计算开始~~~')
    r = add(a, b)
    print('计算结束~~~')
    return r


r = new_add(111,222)
print(r)

在这里插入图片描述
上边的方式,已经可以在不修改源代码的情况下对函数进行扩展了
但是,这种方式要求我们每扩展一个函数就要手动创建一个新的函数,实在是太麻烦了
为了解决这个问题,我们创建一个函数,让这个函数可以自动的帮助我们生产函数

def add(a, b):
    '''
        求任意两个数的和
    '''
    r = a + b
    return r


def mul(a, b):
    '''
        求任意两个数的积
    '''
    r = a * b
    return r

def begin_end(old):
    '''
        用来对其他函数进行扩展,使其他函数可以在执行前打印开始执行,执行后打印执行结束

        参数:
            old 要扩展的函数对象
    '''

    # 创建一个新函数
    def new_function(*args, **kwargs):
        print('开始执行~~~~')
        # 调用被扩展的函数,直接把要扩展的函数当参数传进来就行了
        result = old(*args, **kwargs)
        print('执行结束~~~~')
        # 返回函数的执行结果
        return result

    # 返回新函数        
    return new_function


f2 = begin_end(add)
f3 = begin_end(mul)



s = f2(123,456)
r = f3(123,456)
print(r)
print(s)

在这里插入图片描述

装饰器的语法糖@

装饰器的语法使用 @decorator_name 来应用在函数或方法上来装饰当前的函数
可以同时为一个函数指定多个装饰器,这样函数将会安装从内向外的顺序被装饰

相当于把新函数作为参数传入@的函数里面。

def fn3(old):
    '''
        用来对其他函数进行扩展,使其他函数可以在执行前打印开始执行,执行后打印执行结束

        参数:
            old 要扩展的函数对象
    '''

    # 创建一个新函数
    def new_function(*args, **kwargs):
        print('fn3装饰~开始执行~~~~')
        # 调用被扩展的函数
        result = old(*args, **kwargs)
        print('fn3装饰~执行结束~~~~')
        # 返回函数的执行结果
        return result

    # 返回新函数
    return new_function


# 相当于把 say_hello()函数作为参数传入fn3()函数

def say_hello():
    print('大家好~~~')


cms = fn3(say_hello)
cms()

在这里插入图片描述

def fn3(old):
    '''
        用来对其他函数进行扩展,使其他函数可以在执行前打印开始执行,执行后打印执行结束

        参数:
            old 要扩展的函数对象
    '''

    # 创建一个新函数
    def new_function(*args, **kwargs):
        print('fn3装饰~开始执行~~~~')
        # 调用被扩展的函数
        result = old(*args, **kwargs)
        print('fn3装饰~执行结束~~~~')
        # 返回函数的执行结果
        return result

    # 返回新函数
    return new_function


# 相当于把 say_hello()函数作为参数传入fn3()函数
@fn3
def say_hello():
    print('大家好~~~')


say_hello()

在这里插入图片描述

语法糖是支持多层装饰的,写法上从下到上,函数嵌套从内到外对应

def begin_end(old):
    '''
        用来对其他函数进行扩展,使其他函数可以在执行前打印开始执行,执行后打印执行结束

        参数:
            old 要扩展的函数对象
    '''

    # 创建一个新函数
    def new_function(*args, **kwargs):
        print('开始执行~~~~')
        # 调用被扩展的函数,直接把要扩展的函数当参数传进来就行了
        result = old(*args, **kwargs)
        print('执行结束~~~~')
        # 返回函数的执行结果
        return result

    # 返回新函数        
    return new_function


def fn3(old):
    '''
        用来对其他函数进行扩展,使其他函数可以在执行前打印开始执行,执行后打印执行结束

        参数:
            old 要扩展的函数对象
    '''

    # 创建一个新函数
    def new_function(*args, **kwargs):
        print('fn3装饰~开始执行~~~~')
        # 调用被扩展的函数
        result = old(*args, **kwargs)
        print('fn3装饰~执行结束~~~~')
        # 返回函数的执行结果
        return result

    # 返回新函数
    return new_function


# 相当于把 say_hello()函数作为参数传入fn3()函数
@fn3
@begin_end
def say_hello():
    print('大家好~~~')


say_hello()

在这里插入图片描述

def begin_end(old):
    '''
        用来对其他函数进行扩展,使其他函数可以在执行前打印开始执行,执行后打印执行结束

        参数:
            old 要扩展的函数对象
    '''

    # 创建一个新函数
    def new_function(*args, **kwargs):
        print('开始执行~~~~')
        # 调用被扩展的函数,直接把要扩展的函数当参数传进来就行了
        result = old(*args, **kwargs)
        print('执行结束~~~~')
        # 返回函数的执行结果
        return result

    # 返回新函数        
    return new_function


def fn3(old):
    '''
        用来对其他函数进行扩展,使其他函数可以在执行前打印开始执行,执行后打印执行结束

        参数:
            old 要扩展的函数对象
    '''

    # 创建一个新函数
    def new_function(*args, **kwargs):
        print('fn3装饰~开始执行~~~~')
        # 调用被扩展的函数
        result = old(*args, **kwargs)
        print('fn3装饰~执行结束~~~~')
        # 返回函数的执行结果
        return result

    # 返回新函数
    return new_function


# 相当于把 say_hello()函数作为参数传入fn3()函数

@begin_end
@fn3
def say_hello():
    print('大家好~~~')


say_hello()

在这里插入图片描述

def begin_end(old):
    '''
        用来对其他函数进行扩展,使其他函数可以在执行前打印开始执行,执行后打印执行结束

        参数:
            old 要扩展的函数对象
    '''

    # 创建一个新函数
    def new_function(*args, **kwargs):
        print('开始执行~~~~')
        # 调用被扩展的函数,直接把要扩展的函数当参数传进来就行了
        result = old(*args, **kwargs)
        print('执行结束~~~~')
        # 返回函数的执行结果
        return result

    # 返回新函数        
    return new_function


def fn3(old):
    '''
        用来对其他函数进行扩展,使其他函数可以在执行前打印开始执行,执行后打印执行结束

        参数:
            old 要扩展的函数对象
    '''

    # 创建一个新函数
    def new_function(*args, **kwargs):
        print('fn3装饰~开始执行~~~~')
        # 调用被扩展的函数
        result = old(*args, **kwargs)
        print('fn3装饰~执行结束~~~~')
        # 返回函数的执行结果
        return result

    # 返回新函数
    return new_function


# 相当于把 say_hello()函数作为参数传入fn3()函数

@begin_end
@fn3
@begin_end
def say_hello():
    print('大家好~~~')


say_hello()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值