Python 学习日记第七篇 -- 函数相关

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 学习日记第七篇 -- 函数相关相关的知识,希望对你有一定的参考价值。

一、装饰器前戏-闭包
简单来说,python中函数的闭包就是在内部函数里对外部作用域(但不是全局作用域)的变量进行引用,这么说,不太好理解,下面的示例帮助理解

def outer():
    a = 1
    def inner():    # 内部函数inner
        print(a)    # 调用外部环境变量
    return inner

f = outer()
f()

上面的示例就是一个闭包,inner是个内部函数,inner里调用外部作用域变量a,a不是全局变量;这样构成了一个闭包。上面这个例子外部变量是给定的,那么我们通过传参来给定外部变量

def outer(a):
    def inner():    # 内部函数inner
        print(a)    # 调用传入的外部环境变量
    return inner

f = outer(10)
f()

二、装饰器
装饰器也是函数,它实现的功能是在不改动原有函数代码的条件下,添加新的功能,装饰器的返回值也是函数对象。
先来看一个简单的例子

def fun1():
    print("111222333")

这是甲写的一个函数,我们要记录执行函数的日志

def fun1():
    print("111222333")
    logging.info("Program is running")

如上,我们导入了logging模块,在fun1函数中加入日志记录,简单实现了功能,但是如果这样需要记录日志的函数有很多个,我们在一个个的加的话,就会有大量的重复,这种情况下,我们就需要使用装饰器,来抽离出与函数功能无关的重复代码。
下面是一个简单的装饰器:

import logging
def outer(f):
    def inner():
        f()
        logging.warn("Program is running")
    return inner
def fun1():
    print("111222333")
fun1 = outer(fun1)
fun1()

函数outer就是一个装饰器函数,他把fun1包裹起来,但是fun1 = outer(fun1),这句需要在每一个需要被装饰的函数下重新赋值,这个怎们办呢,可以用装饰器特有的语法来解决

import logging

def outer(f):
    def inner():
        f()
        logging.warn("Program is running")
    return inner

@outer
def fun1():
    print("111222333")

@outer
def fun2():
    print("444555666")

fun1()
fun2()

三、带参数的装饰器

上面的例子中,被装饰的函数不带参数,实际上更多情况下函数需要参数,我们来修改一下

import logging

def outer(f):
    def inner(*args,**kwargs):
        f(*args,**kwargs)
        logging.warn("Program is running")
    return inner

@outer
def fun1(*args,**kwargs):
    print(args)

fun1(1,2,3,4,5)

上面的例子使被装饰的函数带上了参数,其实,装饰器还有更大的灵活性,装饰器本身也可以带参数传递

import logging
def outer(log_level):
    def decorator(f):
        def inner(*args,**kwargs):
            f(*args,**kwargs)
            if log_level == "warn":
                logging.warn("Program is running")
        return inner
    return decorator
@outer(log_level="warn")
def fun1(*args,**kwargs):
    print(args)

fun1(1,2,3,4,5)

以上是关于Python 学习日记第七篇 -- 函数相关的主要内容,如果未能解决你的问题,请参考以下文章

Python学习第七篇:sys标准库

Python学习第七篇:sys标准库

Python学习第七篇:sys标准库

python之旅六第七篇面向对象

Python之路第七篇--Python基础之面向对象及相关

Python之路第七篇:Python装饰器