带有一些强制键作为功能输入的字典 [英] Dictionary with some mandatory keys as function input

查看:82
本文介绍了带有一些强制键作为功能输入的字典的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个以字典为参数的函数.我将传递给各种字典的字典,这些字典比函数内部使用的字典要多.另外,我想在函数定义中查看需要哪些键.所以我写

I have a function that has a dictionary as an argument. I will pass various dictionaries to it that have more entries than the few used inside the function. Additionally, I would like to see in the function definition what keys are required. So I write

def fun(indict=dict(apple=None, pear=None)):

但是,该函数现在接受任何输入作为indict.有没有一种聪明的写作方式

However, the function now accepts any input as indict. Is there a smart way for writing

any dictionary that has at least the keys 'apple' and 'pear' is accepted.

类似

def fun(indict=dict(apple=NeedsToBeSpecified, pear=NeedsToBeSpecified)):

推荐答案

在python3.x中,您可以使用

In python3.x, you can use function annotations:

>>> def foo(indict: dict(apple=None, pear=None)):
...     print(indict)
... 
>>> foo(dict())
{}

您甚至可以为现在更广为接受的(解释器)Ellipsis文字

You can even go crazy with the now more widely accepted (by the interpreter) Ellipsis literal

>>> def foo(indict: dict(apple=None, pear=None, extra_items=...)) -> int:
...     if any(x not in indict for x in ('apple', 'pear')):
...         raise ValueError('message here...')
...     print(indict)
...     return 3
... 
>>> foo({})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in foo
ValueError: message here...
>>> foo({'apple':6, 'pear':4})
{'pear': 4, 'apple': 6}
3
>>> foo({'apple':6, 'pear':4, 'carrot':30000})
{'carrot': 30000, 'pear': 4, 'apple': 6}
3

从我的第一个示例中可以看到,注释没有强制执行.您必须在函数本身中执行验证,尽管我想您可以从注解 1 内省所需的键,如果您想使其保持DRY,但是仅仅花2步就不值得了键...

As you can see from my first example, the annotation it doesn't enforce anything. You'd have to perform the validation in the function itself although I suppose you could introspect the required keys from the annotations1 if you wanted to keep it DRY, but it's probably not worth the effort for just 2 keys...

在python2.x中(以及更传统的情况),也许您只想将信息放入文档字符串中;-)-而且我建议您也对python3.x这样做,因为这是传统的地方去寻找文件...

In python2.x (and more traditionally), perhaps you'd just want to put the information in the docstring ;-) -- And I'd recommend you do that for python3.x as well since that's the traditional place to go looking for documentation ...

1 keys = foo.__annotations__['indict'].keys() - {'extra_items'}

更新 请注意,现在像mypy这样的奇特事物闲坐着,这个答案可能有些过时了.您可以考虑使用 TypedDict 进行注释>.如果您使用mypy这样的类型检查器,那应该为您的用户设定期望,甚至可能有助于捕获一些错误.

UPDATE Note that now with fancy things like mypy sitting around, this answer is maybe a little outdated. You might consider annotating with a TypedDict from mypy_extensions. That should set expectations for your users and maybe even help catch some bugs if you use a type-checker like mypy.

from mypy_extensions import TypedDict

class Apple:
    """Represent an Apple."""

class Pear:
    """Represent a Pear."""

# "annotation-type" for a dictionary that has an apple and pear key whose values are Apple and Pear instances.
FruitBowl = TypedDict("FruitBowl": {"apple": Apple, "Pear": Pear})

def foo(indict: FruitBowl) -> int:
    ...

这篇关于带有一些强制键作为功能输入的字典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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