我想在Python中对函数进行深度复制.该副本模块是没有帮助的,根据文件,其中说:
此模块不复制类型,如模块,方法,堆栈跟踪,堆栈帧,文件,套接字,窗口,数组或任何类似类型.它通过返回原始对象来"复制"函数和类(浅和深); 这与pickle模块处理这些方式兼容.
我的目标是让两个函数具有相同的实现,但具有不同的文档字符串.
def A():
"""A"""
pass
B = make_a_deepcopy_of(A)
B.__doc__ = """B"""
Run Code Online (Sandbox Code Playgroud)
那么怎么做呢?
我有很多课程,为不同的网站实现了一些常规任务:
class AbstractCalculator :
pass # ... abstract methods lying here
class Realization1 (AbstractCalculator) :
@classmethod
def calculate_foo(...) :
# ...
@classmethod
def calculate_bar(...) :
# ...
class Realization2 (AbstractCalculator) :
@classmethod
def calculate_foo(...) :
# ...
@classmethod
def calculate_bar(...) :
# ...
Run Code Online (Sandbox Code Playgroud)
然后我在一个字典中汇总所有这些类现在我介绍新的不同的API:
class NewAbstractClass :
# ... introducting new API ...
@staticmethod
def adopt(old_class) :
# .. converting AbstractClass to NewAbstactClass
Run Code Online (Sandbox Code Playgroud)
然后我使用像@decorator这样的adopt()方法将所有旧的实现转换为新的.
但这一切都非常奇怪和复杂.有没有更好的方法来做到这一点?
UPD @ColinMcGrath:
不,我肯定要问别人.
我的adopt()装饰器正在工作,我没有问题它的功能(只是,它的主体与我的问题无关,所以我没有提供它).
我认为在源代码中对几十个不同类的硬编码装饰并不是最好的主意,并且正在寻找规范的搜索.
假设我有两个模块:
a.py
value = 3
def x()
return value
Run Code Online (Sandbox Code Playgroud)
b.py
from a import x
value = 4
Run Code Online (Sandbox Code Playgroud)
我的目标是使用a.xin的功能b,但更改函数返回的值。具体来说,即使我运行,也会作为全局名称的来源value进行查找。我基本上试图创建函数对象的副本,该副本与该副本相同,但用于获取其全局变量。有没有一种相当简单的方法来做到这一点?ab.x()b.xa.xb
这是一个例子:
import a, b
print(a.x(), b.x())
Run Code Online (Sandbox Code Playgroud)
目前的结果是3 3,但我希望是这样3 4。
我想出了两种有效的复杂方法,但我对其中任何一种都不满意:
x在模块中重新定义。b真正的功能比显示的要复杂得多,所以这不适合我。定义一个可以传递给 x 的参数并仅使用模块的值:
def x(value):
return value
Run Code Online (Sandbox Code Playgroud)
这给用户增加了我想避免的负担,并没有真正解决问题。
有没有办法以某种方式修改函数获取全局变量的位置?
问题
考虑以下布局:
package/
main.py
math_helpers/
mymath.py
__init__.py
Run Code Online (Sandbox Code Playgroud)
mymath.py包含:
import math
def foo():
pass
Run Code Online (Sandbox Code Playgroud)
我希望main.py能够使用mymath.py这样的代码:
import math_helpers
math_helpers.foo()
Run Code Online (Sandbox Code Playgroud)
为此,__init__.py包含:
from .mymath import *
Run Code Online (Sandbox Code Playgroud)
然而,导入的模块mymath.py现在位于math_helpers命名空间中,例如math_helpers.math可以访问。
目前的方法
我在 的末尾添加以下内容mymath.py。
import types
__all__ = [name for name, thing in globals().items()
if not (name.startswith('_') or isinstance(thing, types.ModuleType))]
Run Code Online (Sandbox Code Playgroud)
这似乎可行,但这是正确的方法吗?