假设(Python):省略argumen

2024-05-14 10:42:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个类似这样的函数(它实际上是一个类,但是对于Python的duck类型来说,这不相关):

def myfunc(a=None, b=None):
    <snip>

现在我想写一个假设检验,它总是提供a,但有时{}。在

我试过了

^{pr2}$

但是当它得到strat.nothing()时,它似乎只是跳过了那个测试运行(我得到了hypothesis.errors.FailedHealthCheck: It looks like your strategy is filtering out a lot of data.,当使用它作为b的唯一策略时)。在

我怎么能有时用假设检验来证明论点呢?我需要写两个测试吗,一个有b,一个没有?在


Tags: 函数none类型defitmyfuncsniphypothesis
3条回答

看起来您想要none()而不是nothing()

from hypothesis import given, strategies as strat

@given(a=strat.booleans(), b=strat.none() | strat.integers(min_value=1))
def test_model_properties(self, **kwargs):
    myval = myfunc(**kwargs)
    ...

这比生成用作**kwargs的字典更简单,效率也更高一些。对b的策略排序也很重要——首先将none()放在首位,以确保最小的示例将是a=False, b=None,而不是{}。在

还要注意,多次应用@given与一次使用相比效率非常低,而且实际上自3.34.0版以来就已经弃用了。在

您的方法保证会失败,因为hypothesis docs所暗示的

hypothesis.strategies.nothing()[source]

    This strategy never successfully draws a value and will always reject on an attempt to draw.

尝试不为^{cd1>}提供值将始终失败。

这件事怎么样:

^{pr2}$

在一系列试验中,我得到了一些输出,例如^{{cd2>}、^{cd3>}、^{cd4>}、^{cd5>}和^{cd6>}。

当然,您将使用此选项^{{cd7>}而不是^{{cd8>}。

jacq's answer把我放在正确的轨道上-关键字的选择需要有自己的策略。在

用标准字典

std = {'a': strat.booleans()}

和可选字典

^{pr2}$

然后我可以将chained list comprehension用于所有可能的“可选参数组合”:

# chain.from_iterable may or may not be faster; it doesn't matter for me.
optional = [combo
            for n in range(len(opt.items()))
            for combo in itertools.combinations(opt.items(), n+1)]

bc和{}生成键值元组。在

为了绘制一组值,我们需要得到其中一个选项,可以用sampled_from(optional)完成。对于获得的元组,除了std字典中的策略之外,我们还必须从中提取策略。在

strat.sampled_from(optional).flatmap(
    lambda x: strat.fixed_dictionaries(
        {**std, **dict(x)}
    )
)

这些都可以包装在一个函数中,我们称之为valid_values()。如果在包装函数的签名中指定*args或{},则不能使用@given(valid_values())。在

结果,test_model_properties(self, **kwargs)变成了test_model_properties(self, kwargs)(您可以使用@given(kwargs=valid_values()))-通过调用字典kwargs,函数的其余部分保持不变。在

注意:如果您希望没有可选参数的可能性,这将不包括空元组,但是可以很容易地将其附加到optional列表中。因此{{cd16>的长度{。在

相关问题 更多 >

    热门问题