首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何创建python函数的副本

如何创建python函数的副本
EN

Stack Overflow用户
提问于 2012-11-22 06:26:20
回答 1查看 20.9K关注 0票数 30

有没有可能创建python函数的真实副本?最明显的选择是http://docs.python.org/2/library/copy.html,但我在那里读到:

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

我需要一个真正的副本,因为我可能会更改函数的一些属性。

更新:

我知道评论中提到的所有可能性。我的用例是基于元编程的,其中我使用一些声明性规范构造类。完整的细节可能太长了,但基本上我有一个函数,比如

代码语言:javascript
复制
def do_something_usefull(self,arg):
    self.do_work()

我将把这个方法添加到各种类中。这些类可以是完全不相关的。使用混入类是不可取的:我将有许多这样的函数,并最终为每个函数添加一个基类。我目前的“变通办法”是将这个函数包装在一个“工厂”中,如下所示:

代码语言:javascript
复制
def create_do_something():
    def do_something_usefull(self,arg):
        self.do_work()

这样,我总是得到一个新的do_something_useful函数,但我必须像这样包装我的所有函数。

你可以相信我,我知道,这不是“正常”的面向对象编程。我知道如何“正常”地解决这样的问题。但这是一个动态代码生成器,我希望尽可能保持一切轻量级和简单。由于python函数是非常普通的对象,我认为询问如何复制它们并不奇怪!?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-22 06:43:29

Python3

代码语言:javascript
复制
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

收益率

代码语言:javascript
复制
(1, 2, 3, (5,), 4, 'BAR', 'BAZ')
(1, 2, 3, (5,), 4, 'BAR', 'BAZ')
[1, 2, 3]

Python2

代码语言:javascript
复制
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

收益率

代码语言:javascript
复制
(1, 2)
(1, 2)
[1, 2, 3]
票数 42
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13503079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档