如何在 Python 中对函数进行深度复制?
我想在 Python 中制作一个函数的深度复制。根据文档,copy模块没有帮助,其中说:
该模块不复制模块、方法、堆栈跟踪、堆栈帧、文件等类型, 套接字、窗口、数组或任何类似的类型。它确实“复制”函数和类(浅层 并深入),通过不变地返回原始对象;这与方式兼容 这些由 pickle 模块处理。
我的目标是拥有两个具有相同实现但具有不同文档字符串的函数。
def A():
"""A"""
pass
B = make_a_deepcopy_of(A)
B.__doc__ = """B"""
那么如何才能做到这一点呢?
I would like to make a deepcopy of a function in Python. The copy module is not helpful, according to the documentation, which says:
This module does not copy types like module, method, stack trace, stack frame, file,
socket, window, array, or any similar types. It does “copy” functions and classes (shallow
and deeply), by returning the original object unchanged; this is compatible with the way
these are treated by the pickle module.
My goal is to have two functions with the same implementation but with different docstrings.
def A():
"""A"""
pass
B = make_a_deepcopy_of(A)
B.__doc__ = """B"""
So how can this be done?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
FunctionType 构造函数用于制作函数的深层复制。
The FunctionType constructor is used to make a deep copy of a function.
大多数用户都会这样做,假设原始函数在
old_module.py
中:而在
new_module.py
中,这是重用功能的最直接的方法。很容易阅读和理解意图。
尽管如此,也许你对你的主要问题有充分的理由:
为了保持与 Python 2和 3 的兼容性,我建议使用该函数的特殊
__dunder__
属性。例如:这是一个示例用法:
评论者说:
好吧,我不会为内置函数这样做。对于用纯 Python 编写的函数,我没有什么理由这样做,而且我怀疑如果你这样做,你可能会做一些非常错误的事情(尽管我在这里可能是错的)。
如果您想要一个函数执行内置函数的操作,并重用实现,就像副本一样,那么您应该用另一个函数包装该函数,例如:
Most users will do this, say the original function is in
old_module.py
:and in
new_module.py
This is the most straightforward way to reuse functionality. It is easy to read and understand the intent.
Nevertheless, perhaps you have a good reason for your main question:
To keep this compatible with Python 2 and 3, I recommend using the function's special
__dunder__
attributes. For example:And here's an example usage:
A commenter says:
Well I wouldn't do this for a built-in function. I have very little reason to do this for functions written in pure Python, and my suspicion is that if you are doing this, you're probably doing something very wrong (though I could be wrong here).
If you want a function that does what a builtin function does, and reuses the implementation, like a copy would, then you should wrap the function with another function, e.g.:
将其包裹为部分?
Wrap it as a partial?
其他答案不允许使用pickle进行序列化。这里是我用来克隆函数并允许 python3 序列化的代码:
输出:
如果您使用类方法尝试此代码片段,您可能会遇到 qualname 属性问题(我认为 pickle 应该无法找到你的函数)。我从未尝试过,但它应该很容易修复。只需检查有关 qualname 的文档即可
The others answers do not allow for serialization with pickle. Here a code that I am using to clone a function and allow for serialization for python3:
Output:
You may encounter problem with the qualname attribute if you try this snippet with class methods (I think pickle should fail to find your function). I never tried it, however it should be easily fixable. Just check the doc about qualname
使用 lambda 和其余参数很容易做到:
在线尝试!
It's quite easy to do using
lambda
and rest parameters:Try it online!
把它放在一个函数中:
put it in a function:
针对 python3 进行了调整
Adjusted for python3
我在 haggis 中实现了通用函数副本,该库我编写并维护(可通过
pip
使用,但可能不可用conda
)。haggis.objects.copy_func
制作一个副本,您不仅可以在其上重新分配__doc__
属性,还可以有效地修改模块和__globals__
属性。I've implemented a general-purpose function copy in haggis, a library which I wrote and maintain (available with
pip
but probably notconda
).haggis.objects.copy_func
makes a copy on which you can not only reassign the__doc__
attribute, but also modify the module and__globals__
attributes effectively.