Search code examples
pythonfunctionpass-by-referenceimmutability

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


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