Моя цель - иметь две функции с одинаковой реализацией, но с разными строками документации.
Большинство пользователей будут делать это, скажем, исходная функция в old_module.py
:
def implementation(arg1, arg2):
"""this is a killer function"""
и new_module.py
from old_module import implementation as _implementation
def implementation(arg1, arg2):
"""a different docstring"""
return _implementation(arg1, arg2)
Это самый простой способ повторно использовать функциональность. Легко читать и понимать намерения.
Тем не менее, возможно, у вас есть веская причина для вашего основного вопроса:
Как сделать глубокую копию функции в Python?
Чтобы обеспечить совместимость с Python 2 и 3, я рекомендую использовать специальные атрибуты __dunder__
функции. Например:
import types
def 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
А вот пример использования:
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__
Комментатор говорит:
Это не может работать для встроенных функций
Ну, я бы не стал делать для встроенной функции. У меня очень мало причин делать это для функций, написанных на чистом Python, и я подозреваю, что если вы делаете это, вы, вероятно, делаете что-то очень неправильное (хотя я могу ошибаться здесь).
Если вы хотите, чтобы функция выполняла то же, что и встроенная функция, и повторно использовала реализацию, как при копировании, то вам следует обернуть функцию другой функцией, например ::1010
_sum = sum
def sum(iterable, start=0):
"""sum function that works like the regular sum function, but noisy"""
print('calling the sum function')
return _sum(iterable, start)