与PHP的compact()和extract()相当的Python

2024-04-29 00:42:46 发布

您现在位置:Python中文网/ 问答频道 /正文

compact()和extract()是PHP中非常方便的函数。compact()获取符号表中的名称列表,并创建一个仅包含其值的哈希表。提取则相反。e、 g

$foo = 'what';
$bar = 'ever';
$a = compact('foo', 'bar');
$a['foo']
# what
$a['baz'] = 'another'
extract(a)
$baz
# another

在Python中有没有同样的方法?我环顾了四周,最近的一次是this thread,它似乎对它感到不快

我知道locals()、globals()和vars(),但是我怎样才能轻松地选择它们值的子集呢

Python是否有更好的方法来消除这种需求


Tags: 方法函数名称列表fooanotherbarextract
2条回答

它不是很Pythonic,但是如果您确实必须这样做,您可以像这样实现compact()

import inspect

def compact(*names):
    caller = inspect.stack()[1][0] # caller of compact()
    vars = {}
    for n in names:
        if n in caller.f_locals:
            vars[n] = caller.f_locals[n]
        elif n in caller.f_globals:
            vars[n] = caller.f_globals[n]
    return vars

以前可以像这样实现extract(),但在现代Python解释器中,这似乎不再有效了(实际上,这并不是说它曾经“被认为”有效,而是2009年的实现中有一些怪癖让您得以逍遥法外):

def extract(vars):
    caller = inspect.stack()[1][0] # caller of extract()
    for n, v in vars.items():
        caller.f_locals[n] = v   # NEVER DO THIS - not guaranteed to work

如果您真的觉得需要使用这些函数,那么您可能是在用错误的方式做某些事情。它似乎至少在三个方面与Python's philosophy相悖:“显式优于隐式”,“简单优于复杂”,“如果实现很难解释,这是一个坏主意”,也许更多(而且,如果你有足够的Python经验,你知道这样的事情根本做不到)。我可以看到它对于调试器或事后分析非常有用,或者对于某种通常需要创建具有动态选择的名称和值的变量的非常通用的框架非常有用,但这是一种延伸

值得指出的是,extract()(在较小程度上,compact())是PHP最“邪恶”的特性之一(以及register_globalseval),应该避免吗

^{}使确定变量的定义位置变得更加困难。当很难将变量追溯到其定义的位置时,就很难检查常见的安全问题,如使用未初始化的变量,或源于用户输入的未过滤变量

^{}并没有那么糟糕,但如果使用不当,仍然会使查看数组成员从变量中设置的位置变得更加困难

在许多其他语言中extract()的等价物是with关键字。Python现在有一个with关键字,尽管它的工作方式有点不同,这使得它不像extract()。但是,在其他语言(如Javascript)中,with关键字also has a poor reputation

我认为最好的建议是换一种方式思考——与其尝试模仿PHP的一个糟糕特性,不如考虑其他方法,用简洁易读的代码来完成您想要的任务

相关问题 更多 >