我有一个需要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
两次的方法...一次使用默认的numpy
,和来自autograd的numpy
一次。像这样:
useAutograd = False
from lib(useAutograd) import doSomething
useAutograd = True
from lib(useAutograd) import doSomething as doSomethingAutograd
我知道这里有几个选项,但没有一个是令人满意的。
我会复制代码库,并使用默认的numpy
,并使用numpy
中的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)。因此,当用户需要该函数的jacobian时,允许用户使用带autograd
导入的版本,并在他们不需要时使用他们默认的,高度优化的numpy包。 / p>
答案 0 :(得分:3)
如果您希望避免重复代码库,请将您的界面改为一个类。例如:
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)
答案 1 :(得分:1)
您无需做任何事情来实现这一目标。
如果你这样做
from lib import doSomething
from lib_with_autograd import doSomething as doSomethingAutograd
每个函数都使用在其特定模块中导入的numpy
。因此,doSomethingAutograd
使用lib_with_autograd
中导入的doSomething
,lib
使用AudioManager
中导入的文件
答案 2 :(得分:1)
由于python中的所有内容都是一个对象,包括模块,因此您可以执行以下操作:
def doSomething(x, numpy=None):
if numpy is None:
import numpy
return numpy.sqrt(x)
然后你可以在不设置numpy
的情况下调用该函数,然后它将使用默认的numpy。如果你想使用另一个numpy,只需这样称呼它:
from autograd import numpy as autograd_numpy
doSomething(x, numpy=autograd_numpy)