我有一个lib
需要的模块numpy
。例如,假设我有一个假设函数
import numpy
def doSomething(x):
return numpy.sqrt(x)
现在要在单独的模块中使用该功能,我将名称导入为
from lib import doSomething
...
这里是棘手的部分......现在我要揭露的另一个版本doSomething
针对numpy
已经从另一个库中导入(尤其是来自autograd
)。因此,例如,我希望能够有一个功能
from autograd import numpy
def doSomething(x):
return numpy.sqrt(x)
这些功能之间唯一的区别numpy
是从何处导入。特别是,我想doSomething
在同一代码中使用两个版本的,也就是说,我想以某种方式导入doSomething
两次...一次使用default numpy
,一次使用numpy
from autograd。像这样:
useAutograd = False
from lib(useAutograd) import doSomething
useAutograd = True
from lib(useAutograd) import doSomething as doSomethingAutograd
我知道有几个选项,但没有一个令人满意。
我将制作一个代码库的副本,并有一个使用默认值的代码库numpy
和一个使用numpy
from的代码库autograd
。这很不好,因为这将要求我维护两个代码库,它们互为副本,但仅具有不同的导入。
我可以输入条件导入:
try:
from autograd import numpy
except ImportError:
import numpy
这很糟糕,因为用户无法控制要导入的版本...如果他们具有自动分级功能,则他们必须使用该版本。
我可以定义一个环境变量来控制导入
import os
if os.environ.get('AUTOGRADNUMPY'):
try:
from autograd import numpy
except ImportError:
import numpy
else:
import numpy
不利之处在于,尽管用户可以控制导入,但他们只能选择一个版本(据我所知)。因此,他们不能在同一代码中使用两个版本。
此用例有更好的替代方法吗?
感兴趣的背景:
Autograd
它具有自己的一组函数,这些函数可以模拟numpy
并允许人们使用自动微分(与张量流相同)轻松地计算导数,而无需进行昂贵的数值微分。
但是,它们的numpy实现不是最优化的版本(AFAIK)。因此,允许用户在需要使用该autograd
函数的雅可比时使用带有导入的版本,而在不需要时使用其默认的,高度优化的numpy包将是有利的。
如果您希望避免重复代码库,请改为将您的接口设为类。例如:
class using_numpy:
import numpy
@classmethod
def do_something(cls, x):
return cls.numpy.sqrt(x)
class using_autograd(using_numpy):
from autograd import numpy
现在using_numpy.do_something
将使用numpy
,并且using_autograd.do_something
将使用autograd.numpy
。
另外,如果您对感到不舒服classmethod
,可以将您的接口实例设为一个类,例如:
class interface:
def __init__(self, mdl):
self.mdl = mdl
def do_something(self, x):
return self.mdl.sqrt(x)
import numpy
import autograd
with_numpy = interface(numpy)
with_autograd = interface(autograd.numpy)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句