python小知识-上下文管理

简介: 什么是上下文(context)- context是指程序运行所处于的环境和自身的状态(如数据)- 比如上面提到的文件操作,包含了文件打开获取文件操作的句柄权限(获得资源)、处理文件信息、关闭文件(释放资源);这些都是可以认为是文件的操作的环境和状态,也就是一个上下文(context上下文这个译文有点怪怪,可以理解成一个容器内操作一个过程)

python中进行文件操作,经常被建议使用with open的方式,形如:

with open('./dec.py', 'r') as f:
    for line in f.readlines():
        print(line)

why? 这背后的原因是什么?

直观的解释是:这样的好处文件操作是io操作,操作完成之后,需要关闭close,避免文件一直被占用打开。

与之对比另一种写法是:

f = open('./dec.py', 'r')
for line in f.readlines():
    print(line)
f.close()

两种写法对比可以知道:with 方式隐式的帮我们做了资源的释放操作,而这个可能是我们可能遗忘的。

那with是什么?有没有其他的作用?就是今天的主题。

1.with 上下文管理

with是一种python上下文管理方式;什么是上下文(context)

  • context是指程序运行所处于的环境和自身的状态(如数据)
  • 比如上面提到的文件操作,包含了文件打开获取文件操作的句柄权限(获得资源)、处理文件信息、关闭文件(释放资源);这些都是可以认为是文件的操作的环境和状态,也就是一个上下文(context上下文这个译文有点怪怪,可以理解成一个容器内操作一个过程)

所以with上下文管理就是用在某种资源的创建,使用和回收以及异常处理过程中。语法结构如下:

with context_expression [as target(s)]:
    with-body

结合文件操作来说:

  • context_expression:获取资源,获取文件流
  • as target(s): 是可选的,可以认为资源变量
  • with-body: 具体的文件操作

2.如何构建自己的上下文管理

with内部是如何实现的? 从上下文管理的概念可以知道:一个是获取资源,一个是释放资源。

与之对应的,只要实现了下面两个协议的都可以用with来进行上下文管理

  • __enter__: 实现获取资源
  • __exit__: 来实现释放资源的操作

我们来看下具体的例子:

import traceback
class MyWith():
    def __enter__(self):
        print('enter the resource')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print(exc_type, exc_val, exc_tb)
        print('release the resource')
        print(str(traceback.print_exc()))
        # 返回TRUE表示程序已经捕获到异常并处理
        return True
        
    def with_body(self):
        print('this is with body')
    
with MyWith() as res:
    res.with_body()

# enter the resource
# this is with body
# None None None
# release the resource
# None

可以看出 __exit__包含了with-body的异常控制的处理和捕捉,返回TRUE表示程序已经捕获到异常并处理。所以即使你在函数with_body中出现异常情况,程序也会正常执行,除非你在__exit__直接抛出异常。

可以还原下open的写法:

import traceback
class MyOpen():
    def __init__(self, file_name, mode):
        self.file_name = file_name
        self.mode = mode
        self.file = None

    def __enter__(self):
        print('enter the resource')
        self.file = open(self.file_name, self.mode)
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):
        print(exc_type, exc_val, exc_tb)
        print('release the resource')
        print(str(traceback.print_exc()))

        if self.file:
            self.file.close()
        
    
with MyOpen('./dec.py', 'r' ) as f:
    for line in f.readlines():
        print(line)

3.用contextlib简化

对于需要上下文管理的场景,都要建立一个类,并实现 enter 和 __exit__接口来实现上下文管理;有没有更好的方式。

python提供contextlib装饰器来简化上下文管理,具体如下:

import contextlib

@contextlib.contextmanager
def simple_open(file_name, mode):
    # __enter__方法
    print('open file:', file_name, 'in __enter__')
    file_handler = open(file_name, mode)

    try:
        yield file_handler
    except Exception as exc:
        # deal with exception
        print('the exception was thrown')
    finally:
        print('close file:', file_name, 'in __exit__')
        file_handler.close()

        return

with simple_open('./dec.py', 'r') as f:
    for line in f.readlines():
        print(line)

可以看出,

  • contextlib.contextmanager通过yield来代表资源,
  • yield前面的获取资源
  • 通过try...except来进行异常处理,通过finally来做资源释放
目录
相关文章
|
4天前
|
Unix Shell Linux
赞!优雅的Python多环境管理神器!易上手易操作!
赞!优雅的Python多环境管理神器!易上手易操作!
|
4天前
|
存储 Java C语言
【python】——使用嵌套列表实现游戏角色管理
【python】——使用嵌套列表实现游戏角色管理
38 0
|
4天前
|
API 数据库 Python
Python 教程之 Django(8)在 Django 管理界面中渲染模型
Python 教程之 Django(8)在 Django 管理界面中渲染模型
26 0
Python 教程之 Django(8)在 Django 管理界面中渲染模型
|
4天前
|
存储 JSON 数据管理
文件操作与管理:用Python读写数据
【4月更文挑战第8天】本文介绍了Python中进行高效文件操作与数据管理的方法。通过`os`模块管理目录,使用`open`函数读写文件,`pickle`模块保存和加载复杂数据结构。示例代码展示了如何读取和写入文本文件,处理CSV和JSON数据,以及利用`pickle`序列化和反序列化Python对象。掌握这些技能对于处理现代社会中的数据至关重要。
|
2天前
|
Python
空间管理大师已上线!(2),Python高级工程师进阶学习】
空间管理大师已上线!(2),Python高级工程师进阶学习】
|
4天前
|
iOS开发 MacOS Python
Python 虚拟环境及pip环境管理
`venv`是Python的虚拟环境管理工具,提供独立的环境避免包冲突,便于管理与删除。创建虚拟环境使用`python3 -m venv test`,激活环境在Windows上运行`. Scripts\activate`,macOS上运行`. bin\activate`。安装Python包通过`python`或`python3`选择版本,使用`pip`进行安装、升级和卸载。`pip`是Python包管理器,自2.7.9和3.4版本起自带,常用命令包括查看版本、安装、升级和卸载包。为提高速度,可使用国内镜像源如阿里云、清华或豆瓣。
12 2
|
4天前
|
存储 网络安全 数据安全/隐私保护
【专栏】Python 网络设备管理中,`ConnectHandler`(Paramiko库)和`telnetlib`模块常用于设备交互。
【4月更文挑战第28天】Python 网络设备管理中,`ConnectHandler`(Paramiko库)和`telnetlib`模块常用于设备交互。`ConnectHandler`简化SSH连接,便于与网络设备交互,而`telnetlib`是Python内置模块,支持Telnet协议的远程登录操作。两者都提供命令执行和响应接收功能。示例代码展示了如何使用它们获取防火墙设备的版本信息,降低了代码复杂度,提高了可读性和维护性。
|
4天前
|
运维 Shell 网络安全
第十八章 Python批量管理主机(paramiko、fabric与pexpect)
第十八章 Python批量管理主机(paramiko、fabric与pexpect)
|
4天前
|
SQL 安全 Go
如何在 Python 中进行 Web 应用程序的安全性管理,例如防止 SQL 注入?
在Python Web开发中,确保应用安全至关重要,主要防范SQL注入、XSS和CSRF攻击。措施包括:使用参数化查询或ORM防止SQL注入;过滤与转义用户输入抵御XSS;添加CSRF令牌抵挡CSRF;启用HTTPS保障数据传输安全;实现强身份验证和授权系统;智能处理错误信息;定期更新及审计以修复漏洞;严格输入验证;并培训开发者提升安全意识。持续关注和改进是保证安全的关键。
21 0
|
4天前
|
API Python
Python邮件与日历管理
【4月更文挑战第13天】Python 通过 `smtplib` 和 `email` 发送邮件,`imaplib` 接收邮件。`google-api-python-client` 库用于管理 Google Calendar,示例代码展示了列出日历事件的功能。要使用 Google Calendar API,需设置服务帐户凭据和范围。
20 1