script uses up all memory
Marko Rauhamaa
marko at pacujo.net
Thu Mar 6 19:31:13 EST 2014
Chris Angelico <rosuav at gmail.com>:
> On Fri, Mar 7, 2014 at 10:53 AM, Marko Rauhamaa <marko at pacujo.net> wrote:
>> class MyStateMachine:
>> def __init__(self):
>> sm = self
>>
>> class IDLE:
>> def ding(self):
>> sm.open_door()
>> sm.state = AT_DOOR()
>
> Yeah, that's an extremely unusual way to do things. Why keep on
> instantiating objects when you could just reference functions?
That's not crucial. Even if the state objects were instantiated and
inner classes not used, you'd get the same circularity:
class State:
def __init__(self, sm):
self.sm = sm
class Idle(State):
def ding(self):
self.sm.open_door()
self.sm.state = self.sm.AT_DOOR
class AtDoor(state):
...
class MyStateMachine:
def __init__(self):
self.IDLE = Idle(self)
self.AT_DOOR = AtDoor(self)
...
self.state = self.IDLE
The closure style is more concise and to the point and might perform no
worse.
> Nope; certainly not with closures. I do a whole lot of event-driven
> programming (usually in Pike rather than Python, but they work the
> same way in this), and there's no reference loop. Properly-done
> event-driven programming should have two basic states: a reference
> from some invisible thing that can trigger the event (eg a GUI widget)
> to a callable, and a reference from that callable to its state. Once
> the trigger is gone, the callable is dropped, its state is dropped,
> and everything's cleaned up. You don't usually need a reference inside
> the function to that function.
I'm more familiar with networking. If you need a timer, you need to be
able to start it so you need a reference to it. Ok, maybe you
instantiate a new timer each time, but you may need to cancel the timer
so starting the timer gives you a ticket you can use for canceling.
Similarly, you need a socket (wrapper) to signal an I/O state change,
and you also need to be able to close the socket at a bare minimum.
The task scheduling service (asyncio has one) collects thunks that refer
to your objects and your objects have a reference to the task scheduling
service to be able to schedule new tasks.
> Don't forget, a closure need only hang onto the things it actually
> uses. It doesn't need all its locals.
More importantly, there's nothing bad in circularity. No need to avoid
it. No need to cut cords.
Marko
More information about the Python-list
mailing list