How can I make a deepcopy of a function in Python? How can I make a deepcopy of a function in Python? python python

How can I make a deepcopy of a function in Python?


The FunctionType constructor is used to make a deep copy of a function.

import typesdef copy_func(f, name=None):    return types.FunctionType(f.func_code, f.func_globals, name or f.func_name,        f.func_defaults, f.func_closure)def A():    """A"""    passB = copy_func(A, "B")B.__doc__ = """B"""


My goal is to have two functions with the same implementation but with different docstrings.

Most users will do this, say the original function is in old_module.py:

def implementation(arg1, arg2):     """this is a killer function"""

and in new_module.py

from old_module import implementation as _implementationdef implementation(arg1, arg2):    """a different docstring"""    return _implementation(arg1, arg2)

This is the most straightforward way to reuse functionality. It is easy to read and understand the intent.

Nevertheless, perhaps you have a good reason for your main question:

How can I make a deepcopy of a function in Python?

To keep this compatible with Python 2 and 3, I recommend using the function's special __dunder__ attributes. For example:

import typesdef copy_func(f, name=None):    '''    return a function with same code, globals, defaults, closure, and     name (or provide a new name)    '''    fn = types.FunctionType(f.__code__, f.__globals__, name or f.__name__,        f.__defaults__, f.__closure__)    # in case f was given attrs (note this dict is a shallow copy):    fn.__dict__.update(f.__dict__)     return fn

And here's an example usage:

def main():    from logging import getLogger as _getLogger # pyflakes:ignore, must copy    getLogger = copy_func(_getLogger)    getLogger.__doc__ += '\n    This function is from the Std Lib logging module.\n    '    assert getLogger.__doc__ is not _getLogger.__doc__    assert getLogger.__doc__ != _getLogger.__doc__

A commenter says:

This can’t work for built‑in functions

Well I wouldn't do this for a built-in function. I have very little reason to do this for functions written in pure Python, and my suspicion is that if you are doing this, you're probably doing something very wrong (though I could be wrong here).

If you want a function that does what a builtin function does, and reuses the implementation, like a copy would, then you should wrap the function with another function, e.g.:

_sum = sumdef sum(iterable, start=0):    """sum function that works like the regular sum function, but noisy"""    print('calling the sum function')    return _sum(iterable, start)    


from functools import partialdef a():    """Returns 1"""    return 1b = partial(a)b.__doc__ = """Returns 1, OR DOES IT!"""print help(a)print help(b)

Wrap it as a partial?