[英]Generating a dictionary of parameters from keyword arguments
I'm trying to generate a dict containing the names and the value of the non- None
parameters current call.我正在尝试生成一个字典,其中包含当前调用的非
None
参数的名称和值。 This very much feels like something that should be a built-in, but can't find anything that quite does it in the Python documentation.这很像是应该是内置的东西,但在 Python 文档中找不到任何能做到这一点的东西。
For example, when例如,当
def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):
# code to generate dict of non-`None` named arguments (see below)
... # other things happen later
is called with the parameters foo(limit=5, lower_bound=100)
, I need the following dict: {limit=5, lower_bound=100}
.使用参数
foo(limit=5, lower_bound=100)
调用,我需要以下字典: {limit=5, lower_bound=100}
。
Is there something that conveniently does that for me?有什么可以方便地为我做的吗?
So far, I have looked into the following, all of which seem flawed:到目前为止,我已经研究了以下内容,所有这些似乎都有缺陷:
def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):
keys = ('limit', 'offset', 'lower_bound', 'upper_bound')
values = (limit, offset, lower_bound, upper_bound)
magic_dict = {k: v for k, v in zip(keys, values) if v is not None}
locals()
— link — which would need everything removed that shouldn't make it into the dictionary (ie the keys with the value of None
). locals()
—链接— 这将需要删除不应该进入字典的所有内容(即值为None
的键)。 This also seems potentially error prone if variables definitions get added above the magic dictionary code , which would also need to be removed.def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):
magic_dict = {k: v for k, v in locals().items() if v is not None}
inspect
's — link — signature
and bind
, which still requires would a list of the parameters inspect
- 链接- signature
和bind
,这仍然需要参数列表def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):
sig = signature(foo)
sig_args = sig.bind(limit, offset, lower_bound, upper_bound).arguments
magic_dict = {k: v for k, v in sig_args.items() if v is not None}
Other thoughts included making a class to make getattr
available其他想法包括创建一个类以使
getattr
可用
It feels like I'm missing something obvious — feedback would be appreciated!感觉就像我遗漏了一些明显的东西——我们将不胜感激!
Someone suggested What is an elegant way to select all non-None elements from parameters and place them in a python dictionary?有人建议从参数中选择所有非None元素并将它们放入python字典中的优雅方法是什么? , whose responses are primarily "move to
**kwargs
". ,其响应主要是“移至
**kwargs
”。 My initial reaction is that I would prefer to keep a specific list of arguments — is that bad logic by me?我最初的反应是,我更愿意保留一份具体的论据清单——我的逻辑是不是很糟糕? What is typical best practice with Python?
Python 的典型最佳实践是什么?
You can try using decorators:您可以尝试使用装饰器:
def capture(func):
capture.kwds = None
def wrap(*args, **kwargs):
capture.kwds = kwargs
return func(*args, **kwargs)
return wrap
@capture
def foo(limit=None, offset=None, lower_bound=None, upper_bound=None):
return None
Now you can call:现在您可以致电:
>>> foo(limit=1, offset=2, lower_bound=3, upper_bound=4)
None
>>> capture.kwds
{'limit': 1, 'offset': 2, 'lower_bound': 3, 'upper_bound': 4}
You can also use the locals method, but copy the locals at the top of your function.你也可以使用 locals 方法,但是在你的函数顶部复制 locals。 At the end one can use the keys of the original locals and select only those in the return statement:
最后,可以使用原始本地人的键并仅选择返回语句中的键:
def foo(a=None, b=None, c=None):
original_locals = locals().copy()
d = 'test' #Test adding new variable which should not be returned
return {k:v for k,v in locals().items() if k in original_locals.keys() and v is not None}
foo(1)
>> {'a': 1}
foo(1, 2, 3)
>> {'a': 11, 'b': 2, 'c': 3}
Note that you have to copy the locals, otherwise this method will not work.请注意,您必须复制本地人,否则此方法将不起作用。
If you also want to add kwargs
:如果您还想添加
kwargs
:
def func(a=None, b=None, c=None, **kwargs):
org_loc = locals().copy()
def check_kwargs(d):
if 'kwargs' in d.keys():
d.update(d['kwargs'])
del d['kwargs']
check_kwargs(org_loc)
d = 'test'
new_loc = locals()
check_kwargs(new_loc)
return {k:v for k,v in new_loc.items() if k in org_loc.keys() and v is not None}
Then:然后:
func(1)
>> {'a':1}
func(1, test='test')
>> {'a': 1, 'test': 'test'}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.