在python中更改函数的默认参数 [英] Change default arguments of function in python

查看:47
本文介绍了在python中更改函数的默认参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数,可以根据条件将numpy数组转换为包含True或False的数组,然后对彼此相邻的True或False条目进行分组,并计算每个组的长度.这是为了确定给定月份的降水数据中干拼或湿拼的长度.

I have a function that converts a numpy array to a array containing True or False based on a condition then groups the True or False entries that are adjacent to one another and calculates the length of each group. This is to determine the length of dry spells or wet spells in a given month of precipitation data.

这是功能:

import itertools
def spell(X, kind='wet', how='mean', threshold=0.5): 

    if kind=='wet':
        condition = X>threshold
    else:
        condition = X<=threshold

    length = [sum(1 if x==True else nan for x in group) for key,group in itertools.groupby(condition) if key]

    if not length: 
        res = 0
    elif how=='mean': 
        res = np.mean(length)
    else:
        res = np.max(length)

    return res

因此,基本上,对于给定数量的降水数据数组(默认参数设置为湿法术的平均长度),可以选择确定湿法术或干法术的平均长度或最大长度.

So basically there is the option to determine the mean length or maximum length of wet or dry spells given a numpy array of precipitation data with the default parameters set to the mean length of wet spells.

我将此功能与熊猫一起使用,以将其应用于历史记录的每个月:

I use this function with pandas to apply it to each month of a historical record:

#Create example dataframe
np.random.seed(1324)
idx = pd.DatetimeIndex(start='1960-01-01', periods=100, freq='d')
values = np.random.random(100)
df = pd.DataFrame(values, index=idx)

#Apply function
df.resample('M', how=spell)

我得到的是:

0
1960-01-31  1.555556
1960-02-29  1.500000
1960-03-31  1.777778
1960-04-30  6.000000

这是完美的,但是我希望能够即时更改此函数的默认值,以便可以在df.resample()中使用它的其他选项.我已经研究了 functools.partial(),但这仅是针对显式设置输入参数的情况的解决方案. spell(kind ='dry',how ='max',threshold = 0.7).有没有一种方法可以更改函数的默认参数,而无需显式设置后缀,以便我可以将其与 df.resample()一起使用?

Which is perfect, however I want to be able to change the default values of this function somewhat on the fly so that I can use it's other options with df.resample(). I've looked into functools.partial() however this is only a solution for cases where the input arguments are explicitly set ie. spell(kind='dry', how='max', threshold=0.7). Is there a way to change the default arguments of the function in a way they will not need to be explicitly set afterwords so that I can used it with df.resample()?

推荐答案

该函数的默认值存储在该函数的 func_defaults 属性中,该属性是与<函数的 func_code.co_varnames 元组的em> trailing 元素.例如:

The default values for a function are stored in that function's func_defaults attribute, which is a tuple of values which pair up with the trailing elements of the function's func_code.co_varnames tuple. For example:

>>> def foo(x, y=5):
...    return x, y
...
>>> foo(10)
(10, 5)
>>> foo.func_code.co_varnames
('x', 'y')
>>> foo.func_defaults
(5,)
>>> foo.func_defaults = (7,)
>>> foo(10)
(10, 7)

您甚至可以在出现以下情况后为参数提供默认值:

You can even give a parameter a default value after the fact:

>>> foo.func_defaults = (2, 3)
>>> foo()
(2, 3)


警告:我曾想过(ab)使用 mock 库来允许临时覆盖函数默认值,其方式类似于


Warning: I had thought to (ab)use the mock library to allow temporarily overriding the function defaults, in a similar manner to a recent answer of mine. However, it seems to leave the defaults set to None afterward, which means either there is a bug in (or I misunderstand the behavior of) mock, or that messing with functions like this is a little dangerous.

def foo(x=5):
    return x

assert foo() == 5
with mock.patch.object(foo, 'func_defaults', (10,)):
    assert foo() == 10

assert foo() == 5  # Oops; I'm observing foo.func_defaults to be None now

但是,正如您所期望的那样,手动保存和恢复默认设置似乎可以正常工作.

Manually saving and restoring the defaults seems to work fine, though, as you might expect.

orig_defaults = foo.func_defaults
foo.func_defaults = (10,)
assert foo() == 10
foo.func_defaults = orig_defaults
assert foo() == 5

这篇关于在python中更改函数的默认参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆