2012-05-15 133 views
3

我有以下方法:默認值:

def get_data(replace_nan=False): 
    if replace_nan is not False 
     data[numpy.isnan(data)] = replace_nan 
     return data 
    else: 
     return data[~numpy.isnan(data)] 

所以,如果replace_nan是假,我們返回一些數據陣列,但除去NaN秒,如果是別的,我們替換NaN與爭論。

問題是,我可能想用False替換NaN。或者其他任何事情,爲此。什麼是最pythonic方式這樣做?這:

def get_data(**kwargs): 
    if "replace_nan" in kwargs: 
     ... 

的作品,但在語義上是醜陋的(因爲我們真的只是一個關鍵字參數感興趣,replace_nan)任何建議如何處理這種情況?

回答

4

通常人們使用None作爲默認值,然後檢查is not None

如果你需要允許None,也使用虛擬對象:

__default = object() 
def get_data(replace_nan=__default): 
    if replace_nan is __default: 
     ... 
+0

我已經使用了'False',因爲'None'是缺少值的常用替代品。但虛擬的默認對象是整潔的,謝謝! –

2

numpy的判斷爲假內部數組0:

>>>np.array([False,True,2,3]) 
    array([0, 1, 2, 3]) 

所以這可能可能不是你想要的發生。

def get_data(replace_nan=False): 
     if replace_nan: 
      return np.where(np.isnan(data),replace_nan,data) 
     else: 
      return data[~numpy.isnan(data)] 

的numpy.where功能建立與您的條目楠索引的數組。在那裏它用replace_nan替換條目,在其他任何地方保留條目。

manual page

numpy.where(condition[, x, y]) 
Return elements, either from x or y, depending on condition. 
1

我希望把這個如下ThiefMaster的答案,但在留言無格式評論,所以...:

如果您擔心弄亂你的命名空間可以在定義該函數後使用一些技巧 - del變量。

__default = object() 
def get_data(replace_nan=__default, __default=__default): 
    if replace_nan is __default: 
    ... 
del __default 

或者:

__default = object() 
def get_data(replace_nan=__default): 
    if replace_nan is get_data.default_replace_nan: 
    ... 
get_data.default_replace_nan = __default 
del __default 
+0

有趣!然而,我一直認爲'__...'的意思是混亂無論如何;-) –

+0

傳統上__被保留給C編譯器內部的東西,因此是應用程序生成器使用的nono。在Python中,事情有點不同。無論如何:混亂是一個問題。你不能在下一種情況下使用'__default'這個名字,因爲你會在第一次使用時覆蓋'__default'(並且破壞進程中的代碼)。所以應該避免混亂,即使'__'可能會使混亂變得明顯。 – Alfe

1

另一種方式來避免ThiefMaster的做法的雜亂是這樣的:

def get_data(replace_nan=object()): 
    if replace_nan is get_data.func_defaults[0]: 
    ... 

但它使用Python INTERNA這可能不是便攜式(pypy/stackles /下一個版本/ ...)。

+0

你甚至可以用'get_data.func_code.co_varnames.index('replace_nan')'替換上面代碼中的'0',以防止以後修改get_data()的簽名。但是現在我們猜測這個問題已經過時了。 – Alfe