is there a list of
everything that works with the
with statement? or, alternatively, everything that does
not work with the
with statement? i could not find anything at all, one way or the other, regarding how a particular function behaved, so i had to set up a test script.
import os
with os.open('/dev/tty',os.O_WRONLY) as fd:
write(fd,b'foo\n')
write(fd,b'bar\n')
i don't want to have to do this with everything i might use the
with statement with.
(Jan-02-2022, 11:19 PM)Skaperen Wrote: [ -> ]is there a list of everything that works with the with statement? or, alternatively, everything that does not work with the with statement? i could not find anything at all, one way or the other, regarding how a particular function behaved, so i had to set up a test script.
What you can search for is "Context Manager". I think that you'll get more information that way. I can't tell you what does or does not qualify as a context manager but if you want to have some fun fooling around with the idea, you can roll your own. Try this:
from time import time
class Timer : # This is your context manager :)
def __enter__ (self) :
self.start = time ()
return self
def __exit__ (self, *args) :
end = time ()
self.interval = end - self.start
with Timer () as tracker:
for count in range (99999) :
print ('Still working...')
print(f'The loop took {tracker.interval:.3f} seconds.')
If an object has an __enter__()
method and an __exit__()
method, you can normally use it with the with statement.
First attempt to get filename where __enter__ occours:
grep -Rl __enter__ .pyenv/versions/3.11.0a3 | egrep ".py$" | xargs -n1 basename | egrep -v "^test|^_" | sort -u
To gather more information, you have to use some functions from inspect.
It is more difficult to track objects returned by functions from the contextlib module, such as functions decorated by the contextmanager
decorator. They are functions that return contexts.
i made my zopen() class work with with statements (tested). but i was, at first, surprised that os.open() did not work with with. thinking about it, since it returns int, that makes sense.
You could wrap it in a context manager
import contextlib
import os
@contextlib.contextmanager
def osopen(*args, **kwargs):
fd = os.open(*args, **kwargs)
try:
yield fd
finally:
os.close(fd)
s = b'hello world'
with osopen('foo.txt', os.O_WRONLY|os.O_CREAT, 0o666) as fd:
while s:
n = os.write(fd, s)
s = s[n:]
that justifies me digging into more documentation to learn what magic decorators really do.