首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Python中解压**kwargs的相反之处是什么?

在Python中解压**kwargs的相反之处是什么?
EN

Stack Overflow用户
提问于 2022-07-07 02:55:23
回答 1查看 117关注 0票数 1

我一直在学习Python装饰器,并练习使用它们,我正在编写一个日志装饰器,它记录函数何时调用、*args**kwargs传递给函数的时间,以及函数的__repr__,以便以后可以重新评估它。

在Python中,对象的__repr__()方法返回一个字符串,有时可以通过将该字符串传递给eval()来重新创建该对象。我正在尝试为函数实现一种形式的__repr__

由于我使用的是包装任何函数的装饰符,所以我不知道函数的参数是什么,所以我需要使用*args**kwargs来构造__repr__,这是一个字符串,看起来如下所示:

代码语言:javascript
复制
"function_name(positional_arg1, positional_arg2, keyword_arg1='some_value', keyword_arg2='other_value')"

为了创建这个字符串表示,我需要从`kwargs**; that is, convert a dictionary in the form of{'kwarg1':val1(‘kwarg2 2’:val2}to an argument list like:kwarg1=val1,kwarg2=val2` )重构一个参数列表。

(注意:将*args解压缩到参数列表不是问题,因为元组形式的args已经是一种可以接受的格式,可以在去掉元组中的括号后作为位置参数传递给函数。也就是说,args元组:('arg1', 'arg2')只是变成了'arg1', 'arg2'。因此,这个问题的重点是将kwargs字典转换回参数列表。)

下面是我迄今为止所创造的。它很好用,但不太优雅。是否有一种与解压缩kwargs**?**相反的更简单的方法来执行

编辑:我删除了补充代码(例如,设置装潢器),以专注于手头的问题:反包装操作。

代码语言:javascript
复制
def print_args(*args, **kwargs):
    # Generate the kwargs string representation
    kwargs_repr = ''
    # If no kwargs are passed, kwargs holds an empty dictionary (i.e., dict())
    if kwargs != dict():
        num_kwargs = len(kwargs)
        # Convert to format required for an argument list (i.e., key1=val1 rather than {key1: val1})
        for n, (kw, val) in enumerate(kwargs.items()):
            kwargs_repr += str(kw) + '='
            # If the value is a string, it needs extra quotes so it stays a string after being passed to eval().
            if type(val) == str:
                kwargs_repr += '"' + val + '"'
            else:
                kwargs_repr += str(val)
            # Add commas to separate arguments, up until the last argument
            if n < num_kwargs - 1:
                kwargs_repr += ', '
    repr = (
        "print_args("
        # str(args)[1:-1] removes the parentheses around the tuple
        f"{str(args)[1:-1] if args != tuple() else ''}"
        f"{', ' if args != tuple() and kwargs != dict() else ''}"
        f"{kwargs_repr})"
    )
    print(repr)
    return repr


returned_repr = print_args('pos_arg1', 'pos_arg2', start=0, stop=10, step=1) 

输出:

代码语言:javascript
复制
print_args('pos_arg1', 'pos_arg2', start=0, stop=10, step=1)

(归因:我的技术的一些灵感来自于这个堆栈溢出答案:https://stackoverflow.com/a/10717810/17005348)。

注释到目前为止我尝试过的

  • 我知道我可以分别访问argskwargs,比如:

代码语言:javascript
复制
# If I know the name of the function 
# and have stored the args and kwargs passed to the function:
any_func(*args, **kwargs)

# Or, more generally:
kwargs = str(kwargs)[1:-1].replace(': ', '=').replace("'", '')
eval(
    # func_name holds the __name__ attribute of the function
    func_name 
    + '(' 
    + str(args)[1:-1] 
    + ',' 
    + str(kwargs) 
    + ')'
)

..。但是,如果可能的话,我希望使用repr表单,以模仿用于创建对象的语法(即eval(repr(obj))),并避免泛型版本中使用的混乱的字符串连接。

  • list /tuple理解:我的尝试没有奏效,因为每个键值对都变成了一个字符串,而不是整个参数列表,这意味着eval()不能将其识别为关键字参数列表。例如:

代码语言:javascript
复制
print(tuple(str(k) + '=' + str(v) for k, v in kwargs.items()))

输出('key1=val1', 'key2=val2')而不是('key1=val1, key2=val2')

  • 使用repr()函数,如:repr(func(*args, **kwargs))。这没有起作用,因为首先计算的是func().

,因此repr()只返回由repr()返回的值的字符串表示形式

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-07 03:41:40

这里有一些严重的警告,因为并非所有传递给任何类型关键字参数的内容都必须有良好的表示,而且表示可能不像您预期的那样工作(在计算时重构原始文本的副本)。

话虽如此,如下所述:

代码语言:javascript
复制
def print_args(*args, **kwargs):
    print(', '.join(map(repr, args)),
          ', '.join(f'{k}={repr(v)}' for k, v in kwargs.items()))


print_args(1, 'test', [1, 2, 3], a='word', b={'key': 1, 'another': 2})

输出:

代码语言:javascript
复制
1, 'test', [1, 2, 3] a='word', b={'key': 1, 'another': 2}

注意:我没有费心在这两个部分之间打印逗号,我想这是很明显的事情。但万一它惹恼你:

代码语言:javascript
复制
def print_args(*args, **kwargs):
    print(', '.join(list(map(repr, args)) + 
                    [f'{k}={repr(v)}' for k, v in kwargs.items()]))

输出:

代码语言:javascript
复制
1, 'test', [1, 2, 3], a='word', b={'key': 1, 'another': 2}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72891810

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档