#π open("file")
107 messages Β· Page 1 of 1 (latest)
@alpine bear
Remember to:
- Ask your Python question, not if you can ask or if there's an expert who can help.
- Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
- Explain what you expect to happen and what actually happens.
:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.
it creates the object, but open itself doesn't have any dunders
how is it even possible?
it returns a TextIOWrapper
isn't everything in the python associated w/dunde method
:white_check_mark: Your 3.12 eval job has completed with return code 0.
['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__text_signature__']
here's the dunders of the open function
which is going to be pretty much the same signature as any function
!e
print(dir(open) == dir(len))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
True
intersting
but wdym w/this one
open is a function that returns a TextIOWrapper
that's like saying that len should have the same dunders as int
doesn't returning a TextIOWrapper involve using some kind of dunder to do the actrion itself?
no, it's an implementation of the return keyword
oh
the logic behind the with keyword
https://github.com/python/cpython/blob/main/Modules/_io/_iomodule.c#L331 raw file object is created here
Modules/_io/_iomodule.c line 331
raw = PyObject_CallFunction(RawIO_class, "OsOO",```
yea, but I am trying to figure out the meaning of the method in here through the dunder off the open
with method() as object:
#__enter__
...
#__exit__```
!e
import io
fake_file = io.TextIOWrapper(io.StringIO('hello'))
print(dir(fake_file))
:white_check_mark: Your 3.12 eval job has completed with return code 0.
['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'reconfigure', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'write_through', 'writelines']
method here returns a context manager
it simply calls __enter__ on context entry
and __exit__ at the end of context
!e
class Contexter:
def __enter__(self):
print("Context entered")
def __exit__(self, *args):
print("Context exited")
print("Before context")
with Contexter():
print("Inside context")
print("After context")
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | Before context
002 | Context entered
003 | Inside context
004 | Context exited
005 | After context
follow the prints
oh wow
But open is a bit more like this:
class Cm:
def __enter__(self):
return self
def __exit__(self, *exc_info):
return
def method():
return Cm()
See how a function can return an instance of a context manager
So there's no method.__enter__ but it still works
one of the main advantages of this is that __exit__ is called even in the event of an error
so context manager is good for doing some sort of "setup and teardown" but the teardown is always guaranteed to run
class UndoChunk:
def __init__(self, chunk_name=None):
if chunk_name is None:
self.identifier = str(uuid.uuid4())
else:
self.identifier = chunk_name
def __enter__(self):
cmds.undoInfo(openChunk=True, chunkName=self.identifier)
def __exit__(self, *args):
cmds.undoInfo(closeChunk=True, chunkName=self.identifier)
Here's a very simple example of one that I wrote for the software I work with
yeah, the context manager itself is chill, but the method after the with is confusing
this let's me group together multiple operations as a single undo
the method after the with?
are you talking about like as f?
The method from this? ^
no
yeah
It's not usually called a method if it's just a free floating function
what's the point then
!e
class Contexter:
def __enter__(self):
print("Context entered!")
def __exit__(self, *args):
print("Context exited")
def make_context():
return Contexter()
with make_context():
print("Hello")
:white_check_mark: Your 3.12 eval job has completed with return code 0.
001 | Context entered!
002 | Hello
003 | Context exited
methods are class functions meant to be called with an instance
io.open is using the strategy pattern to return an instance of one of two different classes, either a TextIOWrapper instance or a FileIO
yeah, the class it returns is different based on if you use "b" mode or not
okay, then how does the context manager knows what to work with? (which's __enter__ and __exit__ to call)
i've heard that the context manager itself invokes the __enter__ onto the variable that's needed to be worked with and then assigns that returned variable
it ALWAYS must use an instance
so it uses enter/exit of that instance
if you try and use with on an instance without those dunders it will error
so the method() must be initialiser?
No
no, it's simply an instance
It's the strategy selector
I think you're still confused about how open() simply returns an instance of another class
yes π
look at my example here
Initialization is still happening in the classes
make_context() is a function
that function returns an instance of something that implements enter/exit
make_context() doesn't have meaningful dunders
it's the thing being returned that does
oh, i think I got it
would this make sense :
class example:
...
objectt = example()
with objectt:
...```
ohhh, so it's not the method/function but the instance itself..
yes
that clarifies it
but this is strange tho
how?
i was told that everything is done through dunders
on instances, yes
that everything under the hood (during run time) uses dunders
open is not the relevant piece here of making with work properly
i got it, but won't the open itself use dunders to return the instance?
open is no different from any other function
it just so happens to return something that implements enter/exit
oh god
i think I understood my confusiong :
- only the instances have the dunder methods.
- the open is the function, and thus, doesn't have any dunder methods. It literally executes its own c code or something
is this correct?
it doesn't not have dunder methods
it just doesn't have anything meaningful to this operation
a function is still technically an instance
but it's an instance of a function type
Does it go via __call__?
I'd imagine so? The exact implementation is probably C though
oh yes..
alright, it still makes sense
i appreciate your help, @tacit estuary , @wise wraith ! thank you, have a good day :)
!close
This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.