从方法签名中获取 kwargs 的名称,以使用 locals() 将方法签名展平为单个字典
Get name of kwargs from method signature to flatten a method signature into a single dict using locals()
我有一个 class 形式的方法:
def _cool_method(arg1, arg2, **kwargs):
<do pre-processing stuff>
super()._cool_method(**flattened_kwargs)
我希望 flattened_kwargs
成为 dict
,例如:
flattened_kwargs = {
"arg1": value,
"arg2" value,
"kwargs_key1": value,
"kwargs_key2": {"nestedarg1": value, "nestedarg2": value}
"kwargs_key3": value,
}
我需要在子方法中进行一些处理后将单个 kwargs dict
传递给超级调用。
我已经设法弄清楚如何使用 locals()
:
将输入签名扁平化为单个 dict
attrs = locals().copy()
attrs.pop("kwargs")
attrs.update(kwargs)
我现在想将其转换为辅助函数以调用多个子 class 方法。但是,上面的代码假定我知道方法签名定义的 **kwargs
的名称。我想从子方法中检查它,这样我就不需要将假定的密钥硬编码到 pop()
调用中。
我知道在 Python 3.6 中我应该使用 inspect 并且已经做到了这一点:
def _get_signature_kwargs_key(f):
keys = [k for k, v in signature(f).parameters.items() if v.kind == v.VAR_KEYWORD]
return keys[0] if len(keys) == 1 else None
def flatten_signature_args(f, loc):
kwargs_name = _get_signature_kwargs_key(f)
attributes = loc.copy()
# cater for method calls from classes, which include unwanted metadata
for meta in ['__class__', 'self']:
try:
del attributes[meta]
except KeyError:
pass
attributes.pop(kwargs_name)
attributes.update(loc[kwargs_name])
return attributes
出于显而易见的原因,VAR_KEYWORD
唯一性的假设似乎是合理的。但是,是否有更好的方法从签名中提取它,或者是否有更好的方法来满足我对整体签名进行展平的要求?
我还必须在调用 class 方法时进行破解以删除元键,或者当我将 self._cool_method
作为输入函数传递时它会失败。
解决方法:
def get_signature_locals(f, loc):]
return {k: v for k, v in loc.items() if k in signature(f).parameters}
def get_signature_kwargs_key(f):
keys = [k for k, v in signature(f).parameters.items() if v.kind == v.VAR_KEYWORD]
try:
return keys.pop()
except IndexError:
return None
def flatten_signature_kwargs(func, loc):
kwargs_name = get_signature_kwargs_key(func)
attributes = get_signature_locals(func, loc)
if kwargs_name:
attributes.pop(kwargs_name)
attributes.update(loc[kwargs_name])
return attributes
我有一个 class 形式的方法:
def _cool_method(arg1, arg2, **kwargs):
<do pre-processing stuff>
super()._cool_method(**flattened_kwargs)
我希望 flattened_kwargs
成为 dict
,例如:
flattened_kwargs = {
"arg1": value,
"arg2" value,
"kwargs_key1": value,
"kwargs_key2": {"nestedarg1": value, "nestedarg2": value}
"kwargs_key3": value,
}
我需要在子方法中进行一些处理后将单个 kwargs dict
传递给超级调用。
我已经设法弄清楚如何使用 locals()
:
dict
attrs = locals().copy()
attrs.pop("kwargs")
attrs.update(kwargs)
我现在想将其转换为辅助函数以调用多个子 class 方法。但是,上面的代码假定我知道方法签名定义的 **kwargs
的名称。我想从子方法中检查它,这样我就不需要将假定的密钥硬编码到 pop()
调用中。
我知道在 Python 3.6 中我应该使用 inspect 并且已经做到了这一点:
def _get_signature_kwargs_key(f):
keys = [k for k, v in signature(f).parameters.items() if v.kind == v.VAR_KEYWORD]
return keys[0] if len(keys) == 1 else None
def flatten_signature_args(f, loc):
kwargs_name = _get_signature_kwargs_key(f)
attributes = loc.copy()
# cater for method calls from classes, which include unwanted metadata
for meta in ['__class__', 'self']:
try:
del attributes[meta]
except KeyError:
pass
attributes.pop(kwargs_name)
attributes.update(loc[kwargs_name])
return attributes
出于显而易见的原因,VAR_KEYWORD
唯一性的假设似乎是合理的。但是,是否有更好的方法从签名中提取它,或者是否有更好的方法来满足我对整体签名进行展平的要求?
我还必须在调用 class 方法时进行破解以删除元键,或者当我将 self._cool_method
作为输入函数传递时它会失败。
解决方法:
def get_signature_locals(f, loc):]
return {k: v for k, v in loc.items() if k in signature(f).parameters}
def get_signature_kwargs_key(f):
keys = [k for k, v in signature(f).parameters.items() if v.kind == v.VAR_KEYWORD]
try:
return keys.pop()
except IndexError:
return None
def flatten_signature_kwargs(func, loc):
kwargs_name = get_signature_kwargs_key(func)
attributes = get_signature_locals(func, loc)
if kwargs_name:
attributes.pop(kwargs_name)
attributes.update(loc[kwargs_name])
return attributes