我正在教一些邻居的孩子用Python编程.我们的第一个项目是将作为罗马数字给出的字符串转换为阿拉伯语值.
因此,我们开发了一个函数来计算一个罗马数字的字符串,该函数接受一个字符串,并创建一个具有阿拉伯语等价物的列表,以及为评估阿拉伯语等价物而进行的操作.
例如,假设你在XI供给的函数将返回[1,"+",10]如果在IX供给的函数将返回[10," - ",1] 由于我们需要处理其中相邻值相等的情况下另外让我们忽略所提供的值是XII的情况,因为它将返回[1,'=',1,'+',10]以及Roman是IIX的情况,因为它将返回[10,' - ', 1, '=',1]
这是功能
def conversion(some_roman): roman_dict = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M',1000} arabic_list = [] for letter in some_roman.upper(): if len(roman_list) == 0: arabic_list.append(roman_dict[letter] continue previous = roman_list[-1] current_arabic = roman_dict[letter] if current_arabic > previous: arabic_list.extend(['+',current_arabic]) continue if current_arabic == previous: arabic_list.extend(['=',current_arabic]) continue if current_arabic < previous: arabic_list.extend(['-',current_arabic]) arabic_list.reverse() return arabic_list
我可以考虑评估结果的唯一方法是使用eval()
就像是
def evaluate(some_list): list_of_strings = [str(item) for item in some_list] converted_to_string = ''.join([list_of_strings]) arabic_value = eval(converted_to_string) return arabic_value
我对这段代码有点紧张,因为在某些时候我读到eval在大多数情况下都很危险,因为它允许有人在你的系统中引入恶作剧.但我无法想出另一种方法来评估从第一个函数返回的列表.所以无需编写更复杂的功能.
孩子们获得了转换功能,所以即使看起来很复杂,他们也会理解罗马数字转换的过程,这是有道理的.当我们谈论评估虽然我可以看到他们迷路了.因此,我真的希望通过某种方式来评估不需要太多复杂代码的转换函数的结果.
对不起,如果这是扭曲的,我就是这样...
有没有办法在不使用eval的情况下完成eval的功能
当然是.一种选择是将整个事物转换为ast树并自己解析(参见此处的示例).
我对这段代码有点紧张,因为在某些时候我读到eval在大多数情况下都很危险,因为它允许有人在你的系统中引入恶作剧.
这绝对是真的.每当你考虑使用eval时,你需要考虑一下你的特定用例.真正的问题是你相信用户多少以及他们可以造成什么样的伤害?如果您将此作为脚本分发,并且用户仅在自己的计算机上使用它,那么这确实不是问题 - 毕竟,他们不需要将恶意代码注入您的脚本以删除其主目录.如果你打算在你的服务器上托管这个,这完全是另一个故事...然后你需要弄清楚字符串来自何处以及用户是否有任何方式可以修改字符串它不受信任.黑客非常聪明1,2所以在你的服务器上托管这样的东西通常不是一个好主意.(我总是认为黑客比我更了解python WAY).
1 http://blog.delroth.net/2013/03/escaping-a-python-sandbox-ndh-2013-quals-writeup/
2 http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html