Python 'with' statement - how to determine what a module / object / class supports?

Raymond Hettinger surprised many people when he showed slides 36 and 37. https://speakerdeck.com/pyconslides/transforming-code-into-beautiful-idiomatic-python-by-raymond-hettinger - Many knew that the expression c for opening files but not for these new things. Looking at the python 3.3 docs for streams, only at the very bottom, section 16.2.8 is even mentioned. The lecture implied that using the c operator was best practice.

  • How can I determine if c is supported, what it can be attached to, etc.
  • Also, how should one refer to “c”? (threading with statement, python threading lock with statement, ...) what is a normal word to search and see if "c" is supported (we can ask if something iterable is possible, if it asks "acceptable")?

link

+5
source share
3 answers

First, you are not asking if something is “acceptable,” you are asking if it is a “context manager." *

, , (, 3.1, 3.3):

Lock, RLock, Condition, Semaphore BoundedSemaphore with.

, , :

if hasattr(x, '__exit__'):
    print('x is a context manager')

try:
    with x:
        pass
except AttributeError:
    pass
else:
    print('x is a context manager')

:

help(open)...

, , open , , , . 3.3 ; 2.7, (a file), help , , help , , , __exit__.

, , , EAFTP , . - with. , , , , , . ( AttributeError __exit__, , , with, .) , , , , , /etc/. ( stdlib, , - .)

: , close, , contextlib.closing :

with closing(legacy_file_like_object):

...

with closing(legacy_file_like_object_producer()) as f:

, contextlib. @contextmanager , nested , 2.7/3.x 2.5, closing ( @contextmanager), stdlib .


* -, , . help('with') , " " " ". , with foo(bar) as baz, qux as quux:, foo(bar) qux - . (, , - .)

+6

afaik /, __exit__ ( __enter__)

>>>dir(file)
#notice it includes __enter__ and __exit__

def supportsWith(some_ob):
   if "__exit__" in dir(some_ob): #could justas easily used hasattr
       return True
+2

, Python with, . , Pythonic, , , , "context manager-y". ( .)

, "manager manager-y"? : (1) with (2) "" , , , , . .

PEP 343, with , .

A with ,

.

" ". , , , __enter__ __exit__. , , , , , .

, , with? -, __enter__ __exit__ , with. , , .

, . , . __enter__ , as ( , ). with. , __exit__ (, ) , bock, __exit__ .

:

with man as x:         # 1) Look for `man.__enter__` and `man.__exit__`, then ...
                       # 2) Execute `x = man.__enter__()`, then ...
    do_something(x)    # 3) Execute the code in the body of the block, ...
                       # 4) If something blows up, note it (in `err`), ...
                       # 5) Last, this (always!) happens: `man.__exit__(**err)`.
carry_on()

.

?

, __exit__, with . __exit__ ( , err ), .

, with - , , (.. " " ) , . , , .

+1

All Articles