澳门在线威尼斯官方 > 澳门在线威尼斯官方 > python之with语句的原理

原标题:python之with语句的原理

浏览次数:50 时间:2019-09-15

首发时间:2018-02-23 15:28

python之with语句的原理,pythonwith语句

头阵时间:2018-02-23 15:28


事先看来一篇博客说博主python面试时遇上面试官提问with的法规,而那位博主的博文没有谈起with原理,故有此文。

 

 

事先看到一篇博客说博主python面试时相遇面试官提问with的规律,而那位博主的博文未有谈到with原理,故有此文。

1.施行体中发生极其:

import time
class myContextDemo(object):
    def __init__(self,gen):
        self.gen = gen
    def __enter__(self):
        print("enter in ")
        return self.gen
    def __exit__(self, exc_type, exc_val, exc_tb):
#exc_type是exception_type  exc_val是exception_value  exc_tb是exception_trackback
        print("exit in ")
        if exc_type is None:#如果是None 则继续执行
            print("None:",exc_type, exc_val, exc_tb)

        else: #异常不为空时执行,这一步,如果with语句体中发生异常,那么也会执行
            print("exception:", exc_type, exc_val, exc_tb)
            print("all done")



if __name__=="__main__":
    gen=(i for i in range(5,10))
    G=myContextDemo(gen)
    with G as f :
        print("hello")
        for i in f:
            print(i,end="t")
        #测试1:执行体中发生异常
        raise Exception("母鸡啊")
    print("main continue")

结果展现:

1.抛出非常后,后边main continue不再试行

2.__exit__()中的else会执行

 

 

测验2:当else中威吓再次来到为True时:

 

import time
class myContextDemo(object):
    def __init__(self,gen):
        self.gen = gen
    def __enter__(self):
        print("enter in ")
        return self.gen
    def __exit__(self, exc_type, exc_val, exc_tb):
#exc_type是exception_type  exc_val是exception_value  exc_tb是exception_trackback
        print("exit in ")
        if exc_type is None:#如果是None 则继续执行
            print("None:",exc_type, exc_val, exc_tb)

        else: #异常不为空时执行,这一步,如果with语句体中发生异常,那么也会执行
            print("exception:", exc_type, exc_val, exc_tb)
            print("all done")
            return True #这里如果返回true可以看到发生异常后,main continue可以执行
            #即,如果exc_type是true,那么会继续执行,实际上,也可以在这里处理一下异常再返回true


if __name__=="__main__":
    gen=(i for i in range(5,10))
    G=myContextDemo(gen)
    with G as f :
        print("hello")
        for i in f:
            print(i,end="t")
        raise Exception("母鸡啊")
        # print("continue")#这里不会执行
    print("main continue")

结果展现:

1.回到True之后,with会忽略分外,继续施行,所以这里“main continue”能举办

2.不怕忽略非常,在with体中那多少个之后的言语依旧不会举办

附:理论上得以在回到True以前处理一下不胜

 

 

 

 

 

 

 

PS:假诺大家想要了然得更详实,能够本身尝尝去读一下合拉脱维亚语档。

屈居关于with语句的详实介绍官方文档:


首发时间:2018-02-23 15:28 从前看到一篇博客说博主python面试时遇上边试官提问with的法规,而那位博主的...

谷歌(Google)翻译成粤语正是:

with语句用于选拔由上下文管理器定义的主意来封装块的实践(请参见使用语句上下文管理器一节)。 那允许通用的try…except…finally使用形式被封装以便于重用【那句话大约意思便是“with语句”类似于try…except…finally封装之后的的图景】。

满含一个“项目”的with语句的试行进度如下:
1.上下文表明式(在with_澳门在线威尼斯官方 ,item中提交的表达式)被评估以获得上下文管理器。【会分别种类来拍卖,如文件,进程等都能够选用with语句】
2.上下文管理器的__exit __()被加载供之后使用。【担当上下文的脱离】
3.上下文管理器的__enter __()方法被调用。【担当上下文的进去】
4.要是在with语句中蕴藏目的,则将__enter __()的重临值分配给它。【若是with前边随着as 对象(如with open() as f),那么此指标得到with上下文对象的__enter__()的再次来到值,(附:应该是相仿操作数据库时的连年对象和游标的分歧)】

注意
with语句保障,假设__enter __()方法再次来到时并没有错误,那么将一向调用__exit __()。 因而,假若在分配给目的列表时期产生错误,它将被视为与套件内产生的不当同样。 请参阅上边包车型大巴第6步。

5.该套件已实施。【意思正是语句体中的进程实行达成,实践完成就到第六步--调用__exit__()来退出】
6.上下文管理器的__exit __()方法被调用。 假诺不行导致套件退出,则其品种,值和回想作为参数传递给__exit __()。 不然,将提供四个无参数。

关于退出返回值:

If the suite was exited due to an exception, and the return value from the __exit__() method was false, the exception is reraised. If the return value was true, the exception is suppressed, and execution continues with the statement following the with statement.

If the suite was exited for any reason other than an exception, the return value from __exit__() is ignored, and execution proceeds at the normal location for the kind of exit that was taken.

中文:
如果套件由于异常而退出,并且__exit __()方法的返回值为false,则会重新对异常进行重新评估。 如果返回值为true,则异常被抑制,并继续执行with语句后面的语句。

如果套件由于除了异常之外的任何原因而退出,则__exit __()的返回值将被忽略,并且执行将在正常位置继续进行。

 

 

 

意思就是:

如果是异常退出,那么会返回false,(根据文档中的exit的描述“that __exit__() methods should not reraise the passed-in exception; this is the caller’s responsibility.”,大概意思就是exit()不会处理异常,会重新抛出异常抛出给外面,由调用者处理,因为这是调用者的责任)

 

如果返回 True,则忽略异常,不再对异常进行处理【(在exit内部处理完异常后,可以让”__exit__()”方法返回True,此时该异常就会不会再被抛出,with会认为它的执行体没有发生异常)】

 

 

(with会识别重临值,根据再次回到值来管理,若是是False,那么with会将实行体中的分外抛出,倘若是True,那么with会认为尚未发生非常(忽略至极),而继续实践外面包车型地铁讲话,但出于在那之中调用的了__exit__(),所以在极度之后的言语是不会运作的)

 

沾满一个文书档案中提供的三个有关with中动用锁的例子:

澳门在线威尼斯官方 1

 

关于with语句,官方文书档案中是这么描述的:

The with statement is used to wrap the execution of a block with methods defined by a context manager (see section With Statement Context Managers). This allows common try...except...finally usage patterns to be encapsulated for convenient reuse.

 with_stmt ::= "with" with_item ("," with_item)* ":" suite  with_item ::= expression ["as" target] 

The execution of the with statement with one “item” proceeds as follows:

The context expression (the expression given in the with_item) is evaluated to obtain a context manager.

The context manager’s __exit__() is loaded for later use.

The context manager’s __enter__() method is invoked.

If a target was included in the with statement, the return value from __enter__() is assigned to it.

Note
The with statement guarantees that if the __enter__() method returns without an error, then __exit__() will always be called. Thus, if an error occurs during the assignment to the target list, it will be treated the same as an error occurring within the suite would be. See step 6 below.

The suite is executed.

The context manager’s __exit__() method is invoked. If an exception caused the suite to be exited, its type, value, and traceback are passed as arguments to __exit__(). Otherwise, three None arguments are supplied.

 

测量检验2:当else中强制重返为True时:

 

import time
class myContextDemo(object):
    def __init__(self,gen):
        self.gen = gen
    def __enter__(self):
        print("enter in ")
        return self.gen
    def __exit__(self, exc_type, exc_val, exc_tb):
#exc_type是exception_type  exc_val是exception_value  exc_tb是exception_trackback
        print("exit in ")
        if exc_type is None:#如果是None 则继续执行
            print("None:",exc_type, exc_val, exc_tb)

        else: #异常不为空时执行,这一步,如果with语句体中发生异常,那么也会执行
            print("exception:", exc_type, exc_val, exc_tb)
            print("all done")
            return True #这里如果返回true可以看到发生异常后,main continue可以执行
            #即,如果exc_type是true,那么会继续执行,实际上,也可以在这里处理一下异常再返回true


if __name__=="__main__":
    gen=(i for i in range(5,10))
    G=myContextDemo(gen)
    with G as f :
        print("hello")
        for i in f:
            print(i,end="t")
        raise Exception("母鸡啊")
        # print("continue")#这里不会执行
    print("main continue")

结果展现:澳门在线威尼斯官方 2

1.回来True之后,with会忽略分外,继续实行,所以这边“main continue”能施行

2.便是忽略非常,在with体中十一分之后的话语还是不会奉行

附:理论上得以在重临True此前管理一下格外

 

 

 

 

 

 

 

PS:假设我们想要精通得更详尽,能够和睦尝试去读一下官方文书档案。

附上关于with语句的事无巨细介绍官方文书档案:


多少个测验:

本文由澳门在线威尼斯官方发布于澳门在线威尼斯官方,转载请注明出处:python之with语句的原理

关键词:

上一篇:没有了

下一篇:值类型和援用类型,数据类型及差别