簡體   English   中英

Python從模塊兩次導入函數,具有不同的內部導入

[英]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已從另一個庫(尤其是從autogradautograd 因此,例如,我希望能夠有一個功能

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 

我知道有幾個選項,但沒有一個令人滿意。

  1. 我將復制一個代碼庫,並使用默認的numpy復制代碼庫,並使用autograd numpy復制代碼庫。 這很不好,因為這將要求我維護兩個彼此互為副本的代碼庫,只是具有不同的導入。

  2. 我可以輸入條件導入:

     try: from autograd import numpy except ImportError: import numpy 

    這很糟糕,因為用戶無法控制要導入的版本...如果他們具有自動分級功能,則他們必須使用該版本。

  3. 我可以定義一個環境變量來控制導入

     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_autograddoSomething使用一個進口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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM