gpt4 book ai didi

python - 带有位置参数的函数的装饰器,带有通常命名的参数

转载 作者:行者123 更新时间:2023-11-28 22:51:41 24 4
gpt4 key购买 nike

我有一组函数/方法,它们都有不同的位置参数集,在某些情况下还有关键字参数,但共享一个名为 lane_type 的字符串参数。它可以是位置参数或关键字参数。由于设计缺陷(有罪),不同地方的相同值可能在字符串中有大写字母。因此为了比较,我必须将其转换为小写。最终我决定尝试通过装饰器进行转换:

def lt_dec(func):
def _lt_lower(**kwargs):
kwargs['lane_type'] = kwargs['lane_type'].lower()
return func(**kwargs)
return _lt_lower

当然,我尝试测试它 - 但它失败了:

In [38]: @lt_dec
def test1(lane_type):
print lane_type
....:

In [39]: test1('Solid')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/homes/markg/<ipython-input-39-bb6cef5c7fad> in <module>()
----> 1 test1('Solid')

TypeError: _lt_lower() takes exactly 0 arguments (1 given)

显然,我并不完全理解**kwargs 替换机制。我将非常感谢解释我所缺少的内容以及是否有解决我的问题的优雅解决方案。

编辑:

为了清楚起见,我认为我应该展示一些函数定义的例子:这是类中的一个方法

def add_polygon(self, points, lane_type, color):

来自另一个类的方法:

def __init__(self, points, lane_type, color, side=None):

一个函数

def lane_weight(lane_type):

当然,对于具有 1 个参数(我有几个)的函数,解决方案很简单

def lt_dec(func):
def _lt_lower(lane_type):
return func(lane_type)
return _lt_lower

如上文所述 - 是否存在适用于所示所有示例的通用解决方案? (我准备接受否作为答案)

最佳答案

在函数定义中使用**kwargs,您可以将关键字参数(不是位置参数)作为字典:

>>> def lt_dec(func):
... def _lt_lower(**kwargs):
... print 'type(kwargs)=', type(kwargs)
... print 'kwargs=', kwargs
... kwargs['lane_type'] = kwargs['lane_type'].lower()
... return func(**kwargs)
... return _lt_lower
...
>>> @lt_dec
... def test1(lane_type):
... print lane_type
...
>>> test1(lane_type='Solid')
type(kwargs)= <type 'dict'>
kwargs= {'lane_type': 'Solid'}
solid

>>> def lt_dec(func):
... def _lt_lower(*args, **kwargs):
... if args:
... args = (args[0].lower(),) + args[1:]
... elif 'lane_type' in kwargs:
... kwargs['lane_type'] = kwargs['lane_type'].lower()
... return func(*args, **kwargs)
... return _lt_lower
...
>>> @lt_dec
... def test1(lane_type):
... print lane_type
...
>>> test1('Solid')
solid
>>> test1(lane_type='Solid')
solid

更新

使用 inspect.getcallargs :

>>> import inspect
>>>
>>> def lt_dec(func):
... def _lt_lower(*args, **kwargs):
... kwargs = inspect.getcallargs(func, *args, **kwargs)
... if 'lane_type' in kwargs:
... kwargs['lane_type'] = kwargs['lane_type'].lower()
... return func(**kwargs)
... return _lt_lower
...
>>> @lt_dec
... def test1(blah, lane_type):
... print lane_type
...
>>> test1('foo', 'Solid')
solid
>>> test1('foo', lane_type='Solid')
solid

关于python - 带有位置参数的函数的装饰器,带有通常命名的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21279697/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com