无法理解此Python代码的工作方式

时间:2018-09-16 12:00:33

标签: python python-3.x eval args

我在HackerRank上发现了这个问题,我无法理解讨论页面上显示的代码(解决方案)。

问题是: 考虑一个列表(列表= [])。您可以执行以下命令:

插入i e:在位置插入整数。 打印:打印列表。 remove e:删除第一次出现的integer。 append e:在列表末尾插入整数。 sort:对列表进行排序。 pop:弹出列表中的最后一个元素。 反转:反转列表。

即使我使用if-else解决了问题,我也不明白这段代码的工作原理:

n = input()
slist = []
for _ in range(n):
    s = input().split()
    cmd = s[0]
    args = s[1:]
    if cmd !="print":
        cmd += "("+ ",".join(args) +")"
        eval("slist."+cmd)
    else:
        print slist

4 个答案:

答案 0 :(得分:1)

这是肮脏的代码,正在滥用"remove 1"

基本上,例如,当您输入sList.remove(1)时,它会创建一些类似于eval的代码,然后将创建的代码提供给eval。这有Python解释它。

这可能是您在编码竞赛之外解决此问题的最糟糕的方法。这里svg .mat-progress-spinner circle, .mat-spinner circle { stroke: inherit; } 的使用完全没有必要。

答案 1 :(得分:1)

好吧,代码利用了Python的eval函数。许多语言都具有此功能:eval是“求值”的缩写,它接受一段文本并像将其作为程序的一部分一样执行而不是仅将一部分数据馈入程序。这行:

s = input().split()

从用户读取一行输入,并根据空格将其拆分为多个单词,因此,如果您键入“插入1 2”,则s会设置为列表["insert","1","2"]。然后,通过以下几行将其转换为"insert(1,2)",然后将其附加到"slist."并传递给eval,从而导致方法调用slist.insert(1,2)被执行。因此,基本上,这段代码利用了Python已经具有执行所需功能的方法这一事实,甚至碰巧在问题中使用了相同的名称。它所要做的就是从输入行中获取名称和参数,并将其转换为Python语法。 (print选项是特殊情况,因为没有方法slist.print();在这种情况下,它使用全局命令:print slist。)

在实际代码中,您几乎永远不应使用eval;这是一个非常危险的功能,因为它允许您的应用程序用户潜在地使其运行所需的任何代码。对于黑客来说,这无疑是更容易使用的功能之一。

答案 2 :(得分:0)

实际上,我在代码中发现了一些错误,但是我了解了这段代码的运行方式。在这里:

输入:

3
1 2 3
cmd = 1 + ( 2 + 3)

然后eval(cmd),即eval("1 + (2 + 3)")给出输出6 另一个输入:

4 
4 5 6 2
cmd = 4 + ( 5 + 6 + 2)
eval(cmd)

答案 3 :(得分:0)

if __name__ == '__main__':
    N = int(raw_input())
    lst=[]
    for _ in range(N):
        cmd, *line = input().split()
        ele= list(map(str,line))
        if cmd in dir(lst):
            exec('lst.'+cmd+'('+','.join(ele)+')')
        elif cmd == 'print':
            print(lst)
        else:
            print('wrong command', cmd)