本文目录

  • 一、函数的参数引用
  • 1.1、不可变类型
  • 1.2、可变类型
  • 二、函数闭包
  • 2.1、嵌套函数
  • 2.2、闭包
  • 三、装饰器
  • 3.1、带参数的装饰器
  • 3.2、装饰器修饰有返回值函数


一、函数的参数引用

1、在Python中函数参数是传递引用,也就是数据的内存地址。
2、对于不可变类型,修改形参,不影响实参。
3、对于可变类型来说,修改形参,会影响实参。

1.1、不可变类型

不可变类型,例如:

n = 8


def add_num(n):
    n += 3
    print('add_num函数中的n:', n)


add_num(n)
print('全局变量的n:', n)

效果:

python参数 引用 python函数参数引用_开发语言


1.2、可变类型

可变类型,例如:

arr = [9, 8, 7]


def show_list(arr):
    if isinstance(arr, list):
        arr.insert(0, 10)
    print('show_list函数中的arr:', arr)


show_list(arr)
print('全局变量的arr:', arr)

效果:

python参数 引用 python函数参数引用_python参数 引用_02


二、函数闭包

python中函数是一段可以执行的代码,编译完就固定了,每个定义的函数在内存中只有一个实例,运行这个函数就可以执行这个函数,函数也可嵌套定义,就是在函数中可以定义另一个函数,这种嵌套的写法,就会产生闭包问题。

2.1、嵌套函数

def outer():
    a = 101

    def inner():
        b = 202
        # b += a # 内部函数可以使用外部函数的变量,但是不能修改
        nonlocal a # 内部函数引用外部函数加nonlocal
        a += b
        print('内部函数b:', b)
        print('外部函数a:', a)

    print('外部函数a(未改变前):', a)  # 先执行打印a
    inner()  # 后执行改变a

outer()

效果:

python参数 引用 python函数参数引用_内部函数_03


2.2、闭包

符合以下3条的场景称为闭包:

1、嵌套函数
2、内部函数引用了外部函数的变量
3、返回值是内部函数

例如:

def outer(n):
    a = 101

    def inner():
        b = a + n
        return b

    return inner


print(outer(202)())

效果:

python参数 引用 python函数参数引用_内部函数_04


三、装饰器

写代码要遵循开放封闭原则,虽然这个原则是针对面向对象开发,但是适用于函数式编程,规定已经实现的功能代码不允许被修改,但可以被扩展。
装饰器就遵循开放封闭的原则,在不改变原函数的情况下,扩展了函数的功能。
定义装饰器遵循闭包的原则。
例:

def decorators(func):
	print('start')
    def inner():
        func()
        print('铺地板')
        print('刷墙')
    print('end')
    return inner
	
@decorators
def house():
    print('草丕房')


house()

@decorators就是装饰器,它等同于 @decorators = decorators(house)。做到了不影响原函数的同时丰富原函数。效果:

python参数 引用 python函数参数引用_python_05


装饰器的功能应用场景:

1、引入日志
2、函数执行时间统计
3、执行函数前预备处理
4、执行函数后清理功能
5、权限校验等场景
6、缓存


3.1、带参数的装饰器

def decorators(func):
    def inner(htype):
        func(htype)
        print('铺地板')
        print('刷墙')
    return inner


@decorators
def house(htype):
    print('我的房子类型是{}'.format(htype))


house('四合院')

效果:

python参数 引用 python函数参数引用_python参数 引用_06


如果原函数有参数的话,那么装饰器里内部函数也要带参。

在正常开发中,我们写一个装饰器一定要适配多种场景,例如无参,多个参数,关键字参数的场景,例:

def decorators(func):
    def inner(*args, **keywords):
        func(*args, **keywords)
        print('我们生存在地球')
        print('我们要爱护环境')
    return inner


@decorators
def human():
    print('我们是人类')


human()
print('----------------')


@decorators
def bird(atype, canfly):
    print('我是{},我{}'.format(atype, canfly))


bird('鸽子', '会飞')
print('----------------')


@decorators
def animal(atype, canfly, leg=4):
    print('我是{},我{},我有{}条腿'.format(atype, canfly, leg))


animal('狮子', canfly='不会飞')

效果:

python参数 引用 python函数参数引用_python_07


3.2、装饰器修饰有返回值函数

原函数带有返回值,装饰器中也带有返回值:

def decorators(func):
    def inner(*args, **keywords):
        r = func(*args, **keywords)
        print('我们生存在地球')
        print('我们要爱护环境')
        return r
    return inner


@decorators
def animal(atype, canfly, leg=4):
    print('我是{},我{},我有{}条腿'.format(atype, canfly, leg))
    return '狮子王'


r = animal('狮子', canfly='不会飞')
print(r)

效果:

python参数 引用 python函数参数引用_嵌套_08

如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持