[英]python __import__() imports from 2 different directories when same module exists in 2 locations
[英]Python import functions from module twice with different internal imports
我有一個需要numpy
的模塊lib
。 舉例來說,假設我有一個假設函數
import numpy
def doSomething(x):
return numpy.sqrt(x)
現在要在單獨的模塊中使用該功能,我將名稱導入為
from lib import doSomething
...
這是棘手的部分...現在,我想公開另一個版本的doSomething
,該版本的numpy
已從另一個庫(尤其是從autograd
) 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
復制代碼庫,並使用autograd
numpy
復制代碼庫。 這很不好,因為這將要求我維護兩個彼此互為副本的代碼庫,只是具有不同的導入。
我可以輸入條件導入:
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
並允許人們使用自動微分(與tensorflow相同)輕松地計算導數,而無需進行昂貴的數值微分。
但是,它們的numpy實現不是最優化的版本(AFAIK)。 因此,允許用戶在需要使用該函數的autograd
時使用帶有autograd
導入的版本,而在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
感到不舒服,則可以將您的接口實例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)
您無需執行任何操作即可實現此目的。
如果你這樣做
from lib import doSomething
from lib_with_autograd import doSomething as doSomethingAutograd
每個函數都使用在其特定模塊中導入的numpy
。 所以doSomethingAutograd
使用一個進口lib_with_autograd
和doSomething
使用一個進口lib
由於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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.