網頁

2015年7月1日 星期三

[Python][cook][269-269] with 語法

目的: 了解Python with語法

Python with的語法有點像是c++的scope,當進入with區間時, 會進入__enter__function, 當離開with區間時, 會先執行__exit__ function (即使with區間產生exception也會進__exit__)

範例1. __enter__ return自己


#!/usr/bin/python

class A:
        def __init__(self):
                print "__init__"

        def __enter__(self):
                print "__enter__"
                return self

        def __exit__(self, exc_ty, exc_val, tb):
                print "__exit__"

a = A()
with a:
        print " in with "

結果:

__init__
__enter__
 in with x=<__main__ data-blogger-escaped-.a="" data-blogger-escaped-0x7faa8553ac68="" data-blogger-escaped-at="" data-blogger-escaped-instance="">
__exit__

範例2. __enter__ 不return值

#!/usr/bin/python
class A:
        def __init__(self):
                print "__init__"

        def __enter__(self):
                print "__enter__"

        def __exit__(self, exc_ty, exc_val, tb):
                print "__exit__"

a = A()
with a as x:
        print " in with x=%r" % x

結果:

__init__
__enter__
 in with x=None
__exit__

範例3. __enter__ return另一個class的obj


#!/usr/bin/python
#!/usr/bin/python
class B:
        def __init__(self):
                pass

        def showB(self):
                print "This is B"

class A:
        def __init__(self):
                print "__init__"

        def __enter__(self):
                print "__enter__"
                return B()

        def __exit__(self, exc_ty, exc_val, tb):
                print "__exit__"

a = A()
with a as b:
        print " in with "
        b.showB()

結果:

__init__
__enter__
 in with
This is B
__exit__

範例4. with區間有raise Exception

#!/usr/bin/python
class A:
        def __init__(self):
                print "__init__"

        def __enter__(self):
                print "__enter__"
                return self

        def __exit__(self, exc_ty, exc_val, tb):
                print "__exit__ %r %r %r" % (exc_ty, exc_val, tb)

a = A()
with a as x:
        print " in with x=%r" % x
        raise Exception("exp1234")

結果: (可以看到__exit__仍有被執行且__exit__的參數有exception相關資訊)

__init__
__enter__
 in with x=<__main__ data-blogger-escaped-.a="" data-blogger-escaped-0x7f1c4bc0ac68="" data-blogger-escaped-at="" data-blogger-escaped-instance="">
__exit__  Exception('exp1234',) 
Traceback (most recent call last):
  File "./with.py", line 16, in 
    raise Exception("exp1234")
Exception: exp1234

沒有留言:

張貼留言