美文网首页PYTHON进阶
7.魔术方法(2)

7.魔术方法(2)

作者: Stone_説 | 来源:发表于2021-01-10 17:39 被阅读0次

目录:
1.上下文管理对象
2.上下文管理的安全性
3.with语句
4.exit方法的参数

1.上下文管理对象

当一个对象同时出现了enter()和exit()方法,它就属于上下文管理的对象

方法                                        意义
__enter__              进入与此对象相关的上下文,如果存在该方法,with语法会把该方法的返回值作为绑定到as子句中指定的变量上
__exit__               退出与对象相关的上下文
import time

class Point:
    def __init__(self):
        print('init ~~~~~~~~~~~~~~~~~')
        time.sleep(1)
        print('init over')

    def __enter__(self):
        print('enter ~~~~~~~~~~~~~~~~~')

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('exit  ~~~~~~~~~~~~~~~~~~')

with Point() as p:
    print('in with ~~~~~~~~~~~~~~~~~~~')
    time.sleep(2)
    print('with over')

print('==== end ====')

# 运行结果
init ~~~~~~~~~~~~~~~~~
init over
enter ~~~~~~~~~~~~~~~~~
in with ~~~~~~~~~~~~~~~~~~~
with over
exit  ~~~~~~~~~~~~~~~~~~
==== end ====

实例化对象的时候,并不会调用enter,进入with语句块调用enter方法,然后执行语句体,最后离开with语句块的时候,调用exit方法。
with可以开启一个上下文运行环境,在执行前做一些准备工作,执行后做一些收尾工作。
注意:with并不开启一个新的作用域。

2.上下文管理的安全性

异常对于上下文的影响

import time

class Point:
    def __init__(self):
        print('init ~~~~~~~~~~~~~~~~~')
        time.sleep(1)
        print('init over')

    def __enter__(self):
        print('enter ~~~~~~~~~~~~~~~~~')

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('exit  ~~~~~~~~~~~~~~~~~~')

with Point() as p:
    print('in with ~~~~~~~~~~~~~~~~~~~')
    raise Exception('error')
    time.sleep(2)
    print('with over')

print('==== end ====')

# 执行结果
init ~~~~~~~~~~~~~~~~~
Traceback (most recent call last):
  File "C:/Users/dell/PycharmProjects/pythonProject/test2.py", line 17, in <module>
    raise Exception('error')
Exception: error
init over
enter ~~~~~~~~~~~~~~~~~
in with ~~~~~~~~~~~~~~~~~~~
exit  ~~~~~~~~~~~~~~~~~~
# 可以看出enter和exit照样执行,上下文管理是安全的

3.with语句

import time

class Point:
    def __init__(self):
        print('init ~~~~~~~~~~~~~~~~~')
        time.sleep(1)
        print('init over')

    def __enter__(self):
        print('enter ~~~~~~~~~~~~~~~~~')
        return  self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('exit  ~~~~~~~~~~~~~~~~~~')

f = open('animal.py')
with f as p:
    print(f)
    print(p)
    print(f is p)
    print(f == p)

# 执行结果
<_io.TextIOWrapper name='animal.py' mode='r' encoding='cp936'>
<_io.TextIOWrapper name='animal.py' mode='r' encoding='cp936'>
True
True

p = Point()
with p as f:
    print('in with---------------')
    print(p == f)
    print('with over')

print('==== end ====')

# 执行结果
init ~~~~~~~~~~~~~~~~~
init over
enter ~~~~~~~~~~~~~~~~~
in with---------------
True
with over
exit  ~~~~~~~~~~~~~~~~~~
==== end ====

with语法,会调用with后的对象的enter方法,如果有as,则将该方法的返回值赋给as子句的变量。
f = p.enter()

4. exit方法的参数

__enter__方法没有参数
__exit__方法有3个参数,__exit__(self,exc_type,exc_value,traceback)
exc_type: 异常类型
exc_value: 异常的值
tracebask: 异常的追踪信息
__exit__方法返回一个等效True的值,则压制异常,否则,继续抛出异常

例1:
存在未捕获异常

import time

class Point:
    def __init__(self):
        print('init ~~~~~~~~~~~~~~~~~')
        time.sleep(1)
        print('init over')

    def __enter__(self):
        print('enter ~~~~~~~~~~~~~~~~~')
        return  self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print(1,exc_type)
        print(2,exc_val)
        print(3,exc_tb)
        print('exit  ~~~~~~~~~~~~~~~~~~')

p = Point()
with p as f:
    print('in with--------------------')
    raise Exception('Error')
    print('with over')

print('==== end ====')

# 运行结果
init ~~~~~~~~~~~~~~~~~
init over
enter ~~~~~~~~~~~~~~~~~
in with--------------------
1 <class 'Exception'>
2 Error
3 <traceback object at 0x0000024E29255408>
exit  ~~~~~~~~~~~~~~~~~~
Traceback (most recent call last):
  File "C:/Users/dell/PycharmProjects/pythonProject/test2.py", line 22, in <module>
    raise Exception('Error')
Exception: Error

例2:
捕获异常

import time

class Point:
    def __init__(self):
        print('init ~~~~~~~~~~~~~~~~~')
        time.sleep(1)
        print('init over')

    def __enter__(self):
        print('enter ~~~~~~~~~~~~~~~~~')
        return  self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print(1,exc_type)
        print(2,exc_val)
        print(3,exc_tb)
        print('exit  ~~~~~~~~~~~~~~~~~~')

p = Point()
with p as f:
    print('in with--------------------')
    try:
        raise Exception('Error')
    except:
        print('catch my exception')
    print('with over')

# 运行结果
init ~~~~~~~~~~~~~~~~~
init over
enter ~~~~~~~~~~~~~~~~~
in with--------------------
catch my exception
with over
1 None
2 None
3 None
exit  ~~~~~~~~~~~~~~~~~~
==== end ====

相关文章

  • 7.魔术方法(2)

    目录:1.上下文管理对象2.上下文管理的安全性3.with语句4.exit方法的参数 1.上下文管理对象 当一个对...

  • Python学习打call第三十天:魔术方法

    1.什么是魔术方法 在Python中以两个下划线开头和结尾的方法被称为魔术方法,魔术方法都是一些内置方法; 2.基...

  • Python魔术方法

    Python魔术方法 Python 魔术方法指南 — PyCoder’s Weelky CNPython的魔术方法...

  • Python面向对象的魔术方法

    魔术方法 查看类的魔术方法 输出结果如下 在Python中,所有以__双下划线包起来的方法,都统称为魔术方法。比如...

  • python 魔术方法2 序列

    因为python是一个动态语言,它使得继承并不是必须的,它在创建功能完善的序列类型无需使用继承,只需要实现符合序列...

  • 魔术方法及魔术常量详解

    魔术方法 魔术方法中充当了举足轻重的作用,大部分魔术方法起着报错补救措施的作用 __construct()类的构造...

  • PHP 的魔术方法及其应用

    PHP中将所有__(两个下划线)开头的类方法作为魔术方法,这方法之所以称为魔术方法是因为其实现的功能就如变魔术一样...

  • PHP简明教程-面向对象基础 1

    PHP简明教程 面向对象基础 1 类中魔术方法 类中魔术方法不能被手动调用,几乎每个魔术方法都有触发时机和参数,P...

  • 魔术方法(创建属于想自己的序列)

    ### `__len__()`魔术方法: 在使用`len(obj)`的时候,会调用这个魔术方法。 ### `__g...

  • Python 进阶之魔术方法

    Python魔术方法 __开头,__结尾的方法就是魔术方法. 1.__str__格式化输出对象__repr__表示...

网友评论

    本文标题:7.魔术方法(2)

    本文链接:https://www.haomeiwen.com/subject/fclhaktx.html