2012-05-15 132 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