Как создать копию функции Python
Есть ли возможность создавать реальные копии 9X_pythonic функций Python? Самым очевидным выбором 9X_python был http://docs.python.org/2/library/copy.html, но я прочитал:
Он «копирует» функции 9X_python-interpreter и классы (неглубоко и глубоко), возврат 9X_pythonic исходного объекта без изменений;
Мне нужна 9X_deep-copy настоящая копия, потому что я могу изменить 9X_python-interpreter некоторые атрибуты функции.
Обновление:
Я осведомлен 9X_py обо всех возможностях, упомянутых в комментариях. Мой 9X_py вариант использования основан на метапрограммировании, в 9X_python котором я конструирую классы из некоторых 9X_py декларативных спецификаций. Полная информация 9X_deep-copy была бы слишком длинной для SO, но в основном 9X_python-shell у меня есть такая функция, как
def do_something_usefull(self,arg):
self.do_work()
Я добавлю 9X_python-interpreter этот метод в различные классы. Эти классы 9X_pythonista могут быть совершенно не связаны. Использование 9X_deep-copy классов миксинов не вариант: у меня будет 9X_py много таких функций, и в конечном итоге 9X_pythonista я добавлю базовый класс для каждой функции. Моим 9X_python-interpreter текущим «обходным решением» было бы заключить 9X_python-shell эту функцию в «фабрику» следующим образом:
def create_do_something():
def do_something_usefull(self,arg):
self.do_work()
Таким 9X_py образом я всегда получаю новую функцию do_something_useful, но 9X_python-shell мне приходится оборачивать все свои функции 9X_pythonista вот так.
Вы можете мне поверить, что я знаю, что 9X_python это не "нормальное" объектно-ориентированное 9X_py программирование. Я знаю, как "нормально" решать 9X_py что-то подобное. Но это динамический генератор 9X_deep-copy кода, и я хотел бы, чтобы все было максимально 9X_python-shell легким и простым. А поскольку функции Python 9X_pythonic - вполне нормальные объекты, я не думаю, что 9X_deep-copy это слишком странно спрашивать, как их скопировать 9X_py !?
- Если вы меняете атрибуты функции, вам, вероятно, лучше обернуть функцию в объект, а затем изменить атрибуты объекта. Это сделает ваш код чище. Если вы добавите к своему объекту метод `__call__`, его можн ...
Ответ #1
Ответ на вопрос: Как создать копию функции Python
В Python3:
import types
import functools
def copy_func(f):
"""Based on http://stackoverflow.com/a/6528148/190597 (Glenn Maynard)"""
g = types.FunctionType(f.__code__, f.__globals__, name=f.__name__,
argdefs=f.__defaults__,
closure=f.__closure__)
g = functools.update_wrapper(g, f)
g.__kwdefaults__ = f.__kwdefaults__
return g
def f(arg1, arg2, arg3, kwarg1="FOO", *args, kwarg2="BAR", kwarg3="BAZ"):
return (arg1, arg2, arg3, args, kwarg1, kwarg2, kwarg3)
f.cache = [1,2,3]
g = copy_func(f)
print(f(1,2,3,4,5))
print(g(1,2,3,4,5))
print(g.cache)
assert f is not g
урожайность
(1, 2, 3, (5,), 4, 'BAR', 'BAZ')
(1, 2, 3, (5,), 4, 'BAR', 'BAZ')
[1, 2, 3]
В Python2:
import types
import functools
def copy_func(f):
"""Based on http://stackoverflow.com/a/6528148/190597 (Glenn Maynard)"""
g = types.FunctionType(f.func_code, f.func_globals, name=f.func_name,
argdefs=f.func_defaults,
closure=f.func_closure)
g = functools.update_wrapper(g, f)
return g
def f(x, y=2):
return x,y
f.cache = [1,2,3]
g = copy_func(f)
print(f(1))
print(g(1))
print(g.cache)
assert f is not g
урожайность
(1, 2)
(1, 2)
[1, 2, 3]
9X_python
- Также следует скопировать словарь функций: `g ...
-
5
-
2
-
3
-
6
-
1
-
1
-
1
-
1
-
1
-
9
-
6
-
1
-
2
-
1
-
2
-
5
-
1
-
3
-
1
-
2
-
3
-
3
-
30
-
13
-
18
-
7
-
6
-
1
-
10
-
5
-
4
-
7
-
3
-
2
-
2
-
2
-
9
-
2
-
3
-
2
-
7
-
2
-
5
-
5
-
2
-
3
-
5
-
9
-
1
-
2