Skip to content

Standardizing on an (extension) method to reinitialize an object inplace #4331

Closed

Description

@pfalcon

It's well-known that a good way to fight memory fragmentation is preallocation and reuse of buffers objects. "And reuse" clause should not be underestimated, because that's the real action which happens there - a preallocated object is reused, using inplace operations. This is easy for objects like buffers, but this idea can be generalized beyond them. One case is being talked at #2552 (comment) - reusing memoryview with another buffer. But it goes beyond that still. E.g. reusing a closed socket to connect again without allocating a new instance. Reusing uzlib.DecompIO to decompress another stream. Etc.

Related:
#2622, #2552, #2180, #917

P.S. I understand this has zero chance being implemented in the mainline, I'm going to implement this in my fork. Posting here for wider community review.

Activity

  1. pfalcon commented on Dec 1, 2018

    @pfalcon
    ContributorAuthor

    So, neat idea is tore purpose __call__ method for this, leading to "nice" symmetry call a class vs calling an object, where calling a class (allocates and) initializes a new object, where calling an object reinitializes it:

    buf1 = bytearray(10)
    buf2 = bytearray(20)
    
    mv = memoryview(buf1)
    mv(buf2)
    

    However, this won't work for objects which have __call__ already.

    And fairly speaking, this would be called nice strange symmetry, and may confuse novices, and then with some probability and in some contexts experienced user too.

  2. pfalcon commented on Dec 1, 2018

    @pfalcon
    ContributorAuthor

    Then an obvious is to not invent magic syntaxes, but just add a normal method. Name .init() comes to mind. That's a pretty natural name, but it has drawback that it may exist for an object, just the same as __call__. However, objects in the immediate scope of this proposal don't have such. Actually, in MicroPython core API, only machine module classes have it, but semantics nicely matches this proposal - there, .init() is exactly used to reinitialize an object.

    And pretty match, this proposal talks about adding metasemantics to an .init(), that the method can be used for reinitialization of object, not just initialization. It doesn't dictate other aspects of .init().

    So again, the problem are objects which already have .init() in their API (say, coming from CPython). But then this proposal talks only about:

    1. Allowing that .init() method to be called more than once - if that makes sense for that particular .init() method, i.e. it allows to reinitialize enough of object state for the reuse of object in other context.
    2. And if that's not true (existing .init() does not allow to reinitialize enough of object state for the reuse of object in other context), the we just add another signature for .init() to cover the object reuse case, leaving the original .init() alone.
  3. pfalcon commented on Dec 1, 2018

    @pfalcon
    ContributorAuthor

    The other alternative is to add a complete adhoc method like .reuse(...). But as argued in the previous comment, implied semantics of .init() is already pretty close to allow reuse without inventing weird-looking methods, and it should be always possible to extend any existing .init() method to pretty naturally add a reuse case.

  4. pfalcon commented on Dec 1, 2018

    @pfalcon
    ContributorAuthor

    Comments are welcome. I'm already starting to implement this in my fork.

  5. added a commit that references this issue on Mar 9, 2021
  6. dpgeorge commented on May 1, 2026

    @dpgeorge
    Member

    While this is a neat idea, I think it will diverge too much from CPython and make it harder to write code compatible with normal Python.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions