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)

原文地址:http://blog.51cto.com/jiayimeng/2074157

时间: 2024-10-11 16:02:42

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

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

一.函数  1.函数的使用场景及定义 在使用函数编程之前,我们一直是面向过程式编程,语句的堆积造成大量的代码重复,由此,函数应运而生,函数式编程是将反复使用的代码封装到函数中,使用时只需调用即可.函数的学习会让我们更快理解面向对象这一抽象的概念,面向对象即是对函数进行分类和封装. #函数的定义 def first_func():     print("This is my first function!") first_func() def:定义函数的关键字 first_func:函数

Python 学习日记第五篇 -- collections系列

一.计数器(counter) 计数器(counter)以字典的形式返回序列中各个字符出现的次数,值为key,次数为value #!/usr/bin/env python #-*- coding:utf-8 -*- #导入collections模块 import collections counter_test = collections.Counter("asfafjhadgkhjkgfjhgfjhaghdg") print(counter_test) #返回值 C:\Python27

Python 学习日记第三篇 -- 字典

一.字典 python中的字典不是序列,而是一种映射:不通过位置而是通过键存储.字典是可变的. 1.字典的映射操作 使用{}定义字典,以key:value形式存储数据,在字典中key是唯一的 >>> one_dict = {'name':"jym",'age':23,'addr':'xinjiang'} #通过key查找数据 >>> one_dict['name'] 'jym #修改 >>> one_dict['name'] = &

Python 学习日记第六篇 -- 深浅拷贝

深浅拷贝: 1.字符串和数字 import copy #浅拷贝 copy.copy() #深拷贝 copy.deepcopy() ###################################################################################### a1 = "string" #a1 = 11 a2 = a1 a3 = copy.copy(a1) a4 = copy.deepcopy(a1) print(id(a1)) print(

python学习记录第五篇--遍历目录

#coding=utf-8'''@author: 简单遍历目录删除文件的小程序'''import os#查找文件操作def findFile(path): fileList=[] for rootPath,subRoot,fileName in os.walk(path): for sub in fileName: if os.path.isfile(os.path.join(rootPath,sub)): k=os.path.splitext(sub)[1].lower() if k in (

python学习记录第四篇--数据库

只要用到MySQLdb,使用时请先安装MySQLdb,百度上可以下载! #coding=utf-8'''@author: 使用python操作MySQL数据库'''import MySQLdb#import MySQLdb.cursorsconn=MySQLdb.connect(user='root',passwd='root') #connect共三个值,user,passwd,host,无密码且连接本地数据库时,可以都为空.cur=conn.cursor() #创建游标,使用游标进行数据库操

python学习[第十二篇] 数据类型之 集合

python学习[第十二篇] 数据类型之 集合 集合概念 python中集合是一组无序排列的哈希值.集合分为两种可变集合(set)和不可变集合(frozenset) 对可变集合可以修改和删除元素,对于不可变集合不允许.可变集合是不可以哈希的,因此既不能用作字典的键,也不能做其他集合的元素. 集合的增删改查 集合的创建于赋值 集合与列表([]) 和字典({})不同,集合没有特别的语法格式.列表和字典可以通过他们自己的工厂方法创建,这也是集合的唯一的创建方式.set()和frozenset() #创

Python学习总结之一 -- 基础篇

Python学习第一篇 一:写在前面 啊,最近我的新博客一直都没有更新学习内容了,只是最近一直都在忙着寻找实习机会(或许这只是一个借口,真实原因是我太懒惰了,改改改!).终于今天又投递了几个新的实习职位之后幡然醒悟,我的执行力还是太弱了,我得更加有自律性更加坚持才行.所以今天,我把之前学习的Python基础知识总结一下. 二:认识Python 首先我们得清楚这个:Python这个名字是从Monty Python借鉴过来的,而不是源于大家所知道的大蟒蛇的意思.我们为什么要学习Python呢?就我而

python学习之路基础篇(第七篇)

一.模块 configparser XML shutil zipfile 和 tarfile subprocess 二.面向对象 什么是面向对象 self是什么鬼 构造方法 面向对象的三大特性:封装,继承,多态 已经学习过的python内置类:str  list  tuple dict  set python自定义类 python单继承 python多继承