我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python 上下文(Context)学

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python 上下文(Context)学

前言

最早接触到with语句的时候,是初学python,对文件进行读写的时候,当时文件读写一般都是用open()函数来对文件进行读写,为了防止读写的过程中出现错误,也为了让代码更加的pythonic,会接触到with语句

with open('file.text', 'w') as f:
    f.write('hello')

上面的代码仅需两行就实现了对文件进行写入的操作,很方便,代码也更整洁,不会出错。

事实上,上面一段代码就用到了上下文管理器的知识。

某种程度上,上下文管理器可以理解成try/finally的优化,使得代码更加易读,在通常情况下,我们读取文件的时候,如果不适用with语句,为了防止出错,可以采用try/finally的语句来进行读取,使得文件可以正常执行close()方法。

f = open('file.text', 'w'):
    try:
        f.write('hello')
    finally:
        f.close()
        

很明显,with语句比try/finally更易读,更友好。

上下文管理器

上下文管理器协议,是指要实现对象的 __enter__()__exit__() 方法。

上下文管理器也就是支持上下文管理器协议的对象,也就是实现了 __enter__()__exit__() 方法。

上下文管理器 是一个对象,它定义了在执行 with 语句时要建立的运行时上下文。 上下文管理器处理进入和退出所需运行时上下文以执行代码块。 通常使用 with 语句来使用,但是也可以通过直接调用它们的方法来使用。

简单来说,我们定义一个上下文管理器,需要在一个类里面一个实现__enter__(self)__exit__(self, exc_type, exc_value, traceback) 方法。

  • object.__enter__(self)

    进入与此对象相关的运行时上下文,并返回自身或者另一个与运行食上下文相关的对象。(with语句将会绑定这个方法的返回值到 as 子句中指定的目标)

  • object.__exit__(self, exc_type, exc_value, traceback)

    退出关联到此对象的运行时上下文。 各个参数描述了导致上下文退出的异常。 如果上下文是无异常地退出的,三个参数都将为None。如果提供了异常,并且希望方法屏蔽此异常(即避免其被传播),则应当返回真值。 否则的话,异常将在退出此方法时按正常流程处理。请注意__exit__()方法不应该重新引发被传入的异常,这是调用者的责任。如果 with_body 的退出由异常引发,并且__exit__()的返回值等于 False,那么这个异常将被重新引发一次;如果 __exit__() 的返回值等于 True,那么这个异常就被无视掉,继续执行后面的代码。

通常情况下,我们会使用with语句来使用上下文管理器:

with context_expr [as var]:
    with_body

执行过程:

  1. 执行上下文表达式(context_expr)以获得上下文管理器对象。
  2. 加载上下文管理器对象的__exit__()方法,备用。
  3. 执行上下文管理器对象的__enter__()方法。
  4. 如果有as var语句,将__enter__()方法返回值绑定到 as 后面的 变量中。
  5. 执行 with 内的代码块(with_body)。
  6. 执行上下文管理器的__exit__()方法。

把文章开头的例子用上下文管理器实现一边:

class OpenFile(object):
    def __init__(self, filename):
        self.file = open(filename, 'w+')

    def __enter__(self):
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.file.close()


def main():
    with OpenFile('text.txt') as f:
        f.write('ok')

        
if __name__ == "__main__":
    main()

总结:在上下文管理器中,生成类实例的时候,会自动调用__enter__()方法,而在结束的时候,会自动调用__exit__()方法。

所以,在定义上下文管理器的时候,我们只需实现好这两个方法就行了。

上下文管理器的运用场景

上下文管理器的典型用法包括保存和恢复各种全局状态,锁定和解锁资源,关闭打开的文件等。

比如我们需要在一段代码中使用到数据库的查询,可以通过上下文处理器来优化我们的代码结构,

contextilb模块

contextilb模块是python内置模块中的一个用于上下文的模块,可以让我们更优雅地使用上下文管理器。

@contextmanager

这是contextlib模块提供的一个装饰器,用于将一个函数声明上下文管理,无需创建一个类或者单独的__enter__()方法和__exit__()方法,就可以实现上下文管理。

需要注意的是,被装饰的函数被调用的时候必须返回一个生成器,而且这个生成器只生成一个值,如果有as的话,该值讲绑定到with语句as子句的目标中。

from contextlib import contextmanager


@contextmanager
def tag(name):
    print('<{}>'.format(name))
    yield
    print('</{}>'.format(name))


with tag('title'):
    print("This is a contextmanger test")

输出为:

<title>
This is a contextmanger test
</title>

可以看出,输出的流程:

  1. 先输出yield前的输出语句;
  2. 然后再是tag()函数的输出语句,
  3. 最后是yield后面的输出语句。

在生成器函数中的yield之前的语句在__enter__()方法中执行,

相当于

def __enter__(self):
    print('<{}>'.format(name))
    
def __exit__(self, exc_type, exc_val, exc_tb):
    print('</{}>'.format(name))

closing

返回一个上下文管理器,在完成代码块的时候会关闭参数

源码参考:

class closing(AbstractContextManager):

    def __init__(self, thing):
        self.thing = thing
    def __enter__(self):
        return self.thing
    def __exit__(self, *exc_info):
        self.thing.close()

常见用法,如写爬虫的时候,可以这样写:

from contextlib import closing
import requests

url = 'http://www.baidu.com'
with closing(requests.get(url)) as page:
    for line in page:
        print(page)

上下文管理器查询数据库

代码:

import pymysql


class Database(object):
    def __init__(self):
        self.db = pymysql.connect("localhost", "root", "root", "test")
        self.cursor = self.db.cursor()

    def query(self, sql):
        self.cursor.execute(sql)
        result = self.cursor.fetchone()
        return result

    def __enter__(self):   
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.cursor.close()
        self.db.close()



def main():
    sql = "SELECT password FROM USER WHERE username='{}' ORDER BY 1;".format('admin')
    with Database() as s:
        a = s.query(sql)
        print(a)
        

if __name__ == "__main__":
    main()

使用contextlib模块编写:

class Database(object):
    def __init__(self):
        self.db = pymysql.connect("localhost", "root", "root", "test")
        self.cursor = self.db.cursor()

    def query(self, sql):
        self.cursor.execute(sql)
        result = self.cursor.fetchone()
        return result


@contextmanager
def database_query():
    q = Database()
    yield q


def main():
    sql = "SELECT password FROM USER WHERE username='{}' ORDER BY 1;".format('admin')
    with database_query() as s:
        a = s.query(sql)
        print(a)


if __name__ == "__main__":
    main()

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python 上下文(Context)学

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python 上下文(Context)学

前言最早接触到with语句的时候,是初学python,对文件进行读写的时候,当时文件读写一般都是用open()函数来对文件进行读写,为了防止读写的过程中出现错误,也为了让代码更加的pythonic,会接触到with语句with open('
2023-01-30

Golang上下文Context的常见应用场景

Golang context主要用于定义超时取消,取消后续操作,在不同操作中传递值。本文通过简单易懂的示例进行说明,感兴趣的可以了解一下
2023-05-16

Golang上下文Context的常见应用场景

Go语言Context的常见应用场景Context是Go语言中传递请求信息的重要机制。其常见应用场景包括:超时处理取消操作传递上下文数据错误处理并发控制跟踪和监控测试第一方库集成自定义中间件结构化并发最佳实践包括始终传递Context、明确设置截止时间、处理取消、避免泄漏以及利用第三方库支持。
Golang上下文Context的常见应用场景
2024-04-23

我要学python之上下文管理

上下文管理我们通常在写jdbc连接的时候都会写打开连接,使用连接,关闭连接。为了把资源合理利用,同时这些打开,关闭的工作是重复的工作,那么这些活能不能交给工具去做呢?答案肯定是可以的,不然怎么会有那么多的数据层中间件呢?我们要说的这个pyt
2023-01-31

Go语言的context上下文管理怎么使用

这篇文章主要讲解了“Go语言的context上下文管理怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Go语言的context上下文管理怎么使用”吧!context 有什么作用cont
2023-06-29

Golang上下文Context的常见应用场景是什么

这篇文章主要介绍了Golang上下文Context的常见应用场景是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Golang上下文Context的常见应用场景是什么文章都会有所收获,下面我们一起来看看吧。C
2023-07-06

深入学习JavaScript执行上下文

这篇文章主要介绍了深入学习JavaScript执行上下文,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下,希望对你的学习有所帮助
2022-11-13

Python中的with语句与上下文管理器学习总结

0、关于上下文管理器 上下文管理器是可以在with语句中使用,拥有__enter__和__exit__方法的对象。with manager as var:do_something(var)相当于以下情况的简化:var = manager._
2022-06-04

python ftp 上传、下载文件

python ftp 上传、下载文件#获取昨天日期TODAY = datetime.date.today() YESTERDAY = TODAY - datetime.timedelta(days=1)CURRENTDAY=YESTERDA
2023-01-31

PHP学习笔记:文件上传与下载

引言:在现代网络应用中,文件上传与下载是非常常见的功能需求。无论是用户上传图片、音频、视频等文件,还是用户下载网站提供的资源文件,文件上传与下载都是必不可少的功能之一。本文将介绍如何使用PHP语言实现文件上传与下载功能,并提供具体代码示例,
2023-10-21

Golang 文件上传中如何使用 context 超时?

go 中文件上传使用 context 超时可以防止服务器长时间等待客户端完成上传。方法包括:1)创建一个新的 context 对象,设置超时值;2)将 context 对象传递给文件操作;3)使用 ctx.err() 检查是否因超时取消操作
Golang 文件上传中如何使用 context 超时?
2024-05-13

Python上下文管理器Content Manager

在 Python 中,我们会经常听到上下文管理器(Context Manager),那我们探讨下这是什么,又有什么功能。在 Python 中的上下文管理器中,使用 with 打开文件是使用最多的,其中离开 with 包含的语句后会执行一些类
2022-06-02

Python协程中使用上下文

在Python 3.7中,asyncio 协程加入了对上下文的支持。使用上下文就可以在一些场景下隐式地传递变量,比如数据库连接session等,而不需要在所有方法调用显示地传递这些变量。使用得当的话,可以提高接口的可读性和扩展性。协和的上下
2023-01-30

python上下文管理器是什么

本篇文章给大家分享的是有关python上下文管理器是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。python的五大特点是什么python的五大特点:1.简单易学,开发程序
2023-06-14

Python深入02 上下文管理器

上下文管理器(context manager)是Python2.5开始支持的一种语法,用于规定某个对象的使用范围。一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存)。它的语法形式是with...as...关闭文件
2023-06-02

Python上下文管理器深入讲解

Python有三大神器,一个是装饰器,一个是迭代器、生成器,最后一个就是今天文章的主角--「上下文管理器」。上下文管理器在日常开发中的作用是非常大的,可能有些人用到了也没有意识到这一点
2022-12-21

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录