如何创建一个Python函数的副本[复制](How to create a copy of a py

2019-07-04 01:04发布

这个问题已经在这里有一个答案:

  • 我怎样才能使Python中的函数的deepcopy的? 5个回答

是否有创建的Python函数真正副本的可能性? 最明显的选择是http://docs.python.org/2/library/copy.html但我读:

它“复制”函数和类(浅和深),通过返回原始对象不变;

我需要一个真正的副本,因为我可能会改变功能的某些属性。

更新:

我知道这是在评论中提到的所有的可能性。 我用例是基于元编程,我构建类了一些声明规格。 完整的细节将是太长SO,但基本上我有这样一个功能

def do_something_usefull(self,arg):
    self.do_work()

我将这个方法添加到各种类别。 放入系统类可以完全地无关。 使用混入类不是一个选择:我有很多这样的功能,最终会增加一个基类为每个功能。 我现在的“解决办法”将是一个“工厂”这样的包装此功能:

def create_do_something():
    def do_something_usefull(self,arg):
        self.do_work()

这样,我总是得到一个新的do_something_useful功能,但我必须总结我的所有功能,如这一点。

你可以相信我,我知道,这是不是“正常”面向对象编程。 我知道如何解决类似的东西“正常”。 但是,这是一个动态代码生成器,我想保留一切轻量级和简单越好。 随着蟒蛇功能都很正常对象,我不认为它太奇怪地问如何复制他们!?

Answer 1:

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]


文章来源: How to create a copy of a python function [duplicate]