当前位置: 首页 > 面试题库 >

如何创建python函数的副本

都乐逸
2023-03-14
问题内容

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

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

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

更新:

我知道评论中提到的所有可能性。我的用例基于元编程,其中我根据一些声明性规范构造了类。完整的细节对于SO来说太长了,但是基本上我有一个像

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

我将这个方法添加到各种类中。这些类可以完全不相关。使用mixin类不是一种选择:我将拥有许多此类函数,最终将为每个函数添加一个基类。我当前的“解决方法”是将此功能包装在一个“工厂”中,如下所示:

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

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

您可以相信我,我知道,这不是“普通的”
OO编程。我知道如何“正常”解决类似问题。但这是一个动态代码生成器,我想使所有内容尽可能轻巧和简单。而且由于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]


 类似资料:
  • 因为xv中的值可能会改变,xv中的条目数也可能改变,所以我需要能够使用函数来做到这一点? 你知道我怎么做吗?

  • 问题内容: 我实现了此处描述的副本构造函数。但是问题仍然是,当我更新时,会将相同的更新应用于。所以,我不明白我的代码有什么问题? 问题答案: 在复制构造函数中,您只是在进行浅表复制,而您需要进行深表复制: 在这里,您仍在复制的引用,该引用仍指向same 。您也应该对其进行修改以创建列表的副本。可能还需要像下面这样在arraylist中创建元素的副本:

  • 我想列个这样的单子。请帮帮我.谢了。

  • 问题内容: 我正在尝试在Swift中构建Promises的基本实现,并且我需要能够向数组中添加函数,但是我不确定如何使它起作用。 我发现,当我尝试执行以下操作时,Swift Playground不会建议您: 这很有道理-Swift无法推断出-的类型,但这就是我的问题所在。我不确定如何预定义函数数组。 是否可以在Swift中创建函数数组?我想是这样,职能是一等公民。 问题答案: 绝对有可能,只需将数

  • 问题内容: 我有一个带几个参数的Python函数。在某些情况下,可以忽略其中一些参数。 这些参数通过是字符串,每个都有不同的含义。我可以选择要以任何组合形式传递的可选参数,这一点很重要。例如,或,,或,或所有它们(这些是我的选择)。 如果我可以重载该函数,那就太好了-但我读到Python不支持重载。我试图在列表中插入一些必需的int参数-并收到参数不匹配错误。 现在,我正在发送空字符串来代替前几个

  • 问题内容: 我正在尝试在循环内创建函数: 问题在于所有功能最终都相同。这三个函数都没有返回0、1和2,而是返回2: 为什么会发生这种情况,我应该怎么做才能获得分别输出0、1和2的3个不同函数? 问题答案: 你在后期绑定方面遇到了问题-每个函数都i尽可能晚地查找(因此,在循环结束后调用时,i将设置为2)。 可以通过强制早期绑定轻松修复:更改为以下形式: 缺省值(右手i输入i=i是参数名的默认值,i左