Python将字符串转换为参数列表

13

我能否在Python中将一个字符串转换为参数列表?

def func(**args):
    for a in args:
        print a, args[a]

func(a=2, b=3)

# I want the following work like above code
s='a=2, b=3'
func(s)

我知道:

列表可以用*list表示,但是列表不能有像a=2这样的元素。

而且eval只能计算表达式。

def func2(*args):
    for a in args:
        print a

list1=[1,2,3]
func2(*list1)
func2(*eval('1,2,3'))

类似于argparse的东西应该可以解决问题。看一下如何使用参数调用parse_args() - Laur Ivan
3个回答

17
你可以将输入的字符串转换为字典,然后使用该字典调用函数,例如:
>>> x='a=2, b=3'
>>> args = dict(e.split('=') for e in x.split(', '))
>>> f(**args)
a 2
b 3

第一次看到这个语法。谢谢。我不知道为什么 tuple(e.split('=')) for e in x.split(', ') 会导致语法错误,难道它不是 dict() 的参数吗?有关这个规则的解释吗? - Aylwyn Lake
@AylwynLake:这是一个生成器表达式,它本质上是列表推导式的一种广义形式。 - Frerich Raabe
但是a和b是字符串而不是整数。我该如何将它们转换为整数? - zeeshan khan
@zeeshankhan 你可以进一步调整字典,并对所有值应用 int,例如 args = {k: int(v) for k, v in args.items()} - Frerich Raabe

14
你需要的是一个字典,而不是一个“参数列表”。你最好使用ast.literal_eval()来仅评估Python文字:
from ast import literal_eval

params = "{'a': 2, 'b': 3}"
func(**literal_eval(params))

在选择这种方式之前,请确保您已经探索了其他选项来实现选项的编排,比如使用argparse来处理命令行选项,或者使用JSON来进行网络或基于文件的传输或持久化。


2
+1 但是如果a=2,b=3字符串是用户输入(例如来自配置文件或类似文件),则此解决方案可能不适用;您最好不要允许评估任意的Python代码。 :-} - Frerich Raabe
@FrerichRaabe:OP似乎正在寻找这里的args "(1, 2, 3)"func2(*literal_eval(args))的等效物;例如,能够生成正确的Python结构以应用于调用的东西。 - Martijn Pieters
@MartijnPieters:像这样的配置文件,tablename1,id | integer | primary_key,name | varchar(20)|,age | integer | \n tablename2,id | serial | primary_key,user1 | integer | ForeignKey,user2 | integer | ForeignKey,relation | varchar(20)| \n ...我将行拆分后组成表格。但是无法弄清如何构建primary_key = True。 - Aylwyn Lake
@MartijnPieters: print literal_eval("String(20)") 报错 ValueError,而 print eval("String(20)") 输出 VARCHAR(20)。有没有一种折中的方法? - Aylwyn Lake
1
@naxa:没错,那不是Python的字面量,你需要直接解析它。 - Martijn Pieters
显示剩余6条评论

2
您可以将字符串直接作为参数列表在调用eval中使用,例如:
def func(**args):
    for a in args:
        print( a, args[a])

s = 'a=2, b=3'

eval('func(' + s + ')')
>>>b 3
>>>a 2

请注意,func 需要在命名空间中,以便 eval 调用可以像这样工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接