Tuesday, July 5, 2022

[FIXED] How to pass function reference without using mutable type like list or dict

Issue

My goal: pass a reference to a function, and be able to update the function later on.

In Python, I believe functions are passed by reference, but a function's reference is considered immutable. Thus, the function can't be updated later on.

This question gets at the core problem: Python functions call by reference

The answers all point at the workaround: pass the function within a mutable type such as a list or a dict.

I am wondering: is there a more direct way? Might there be some functools function, types utility, or external library that enables this behavior?


Sample Code

**Update**: I am not interested in making foo._on_call public. I am trying to change on_call externally via a reference, not by actually operating directly on the foo object.

from typing import Callable, List

class Foo:
    def __init__(self, on_call: Callable[[], int]):
        self._on_call = on_call

    def __call__(self) -> int:
        return self._on_call()

def do_something() -> int:
    return 0

def do_something_else() -> int:
    return 1

foo = Foo(do_something)

do_something = do_something_else  # Updating do_something
print(do_something())  # This prints 1 now
print(foo())  # This still prints 0, I want this to print 1 now too

Known (undesirable) workarounds:

  • Pass do_something within a list
  • Recreate the foo object
  • Making Foo's _on_call attribute public or using a property decorator

Python version: 3.8


Solution

Functions are actually mutable, via __code__. Here's another example. However, don't know if this is a good idea.

do_something.__code__ = do_something_else.__code__
print(do_something())  # -> 1
print(foo())  # -> 1


Answered By - wjandrea
Answer Checked By - Pedro (PHPFixing Volunteer)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.