本篇文章主要介绍了"编写高质量代码--改善python程序的建议(三)",主要涉及到方面的内容,对于Pythonjrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播感兴趣的同学可以参考一下:
原文发表在我的博客主页,转载请注明出处!建议十三:警惕eval()的安全漏洞
相信经常处理文本数据的同学对eval()一定是欲罢不能,他的使用非常简单:eval...
原文发表在我的博客主页,转载请注明出处!
建议十三:警惕eval()的安全漏洞
相信经常处理文本数据的同学对eval()一定是欲罢不能,他的使用非常简单:
eval("1+1==2") #进行判断
eval("'A'+'B'") #字符连接
eval("1+2") #数字相加
python中eval()函数将字符串str当成有效的表达式来求值并返回计算结果,其函数声明如下:
eval(expression[, globals[,locals]])
#globals为字典形式,表示全局命名空间
#locals为任何映射对象,表示局部命名空间
“eval is evil”,这时一句广为人知的对eval的评价,它主要针对的是eval()的安全性。假设web页面调用eval来根据用户的输入,计算python表达式的值,由于网络环境下运行它的用户并非都是可信任的,eval()可以将任何字符串当作表达式求值,这也就意味着有空子可钻,如果用户输入下面代码,就会得到当前目录下的所有文件列表。
__import__("os").system("dir")
如果有人想搞破坏,他输入了如下字符串(禁止尝试),则会删掉当前目录下的所有文件
__import__("os").system("del * /Q")
当然有人说可以在globals参数中禁止全局命名空间的访问,比如将运算范围限定为几个常用的数学函数:
math_fun_list = ['acos', 'asin', 'atan', 'pi']
math_fun_dict = dict([(k, globals().get(k) for k in math_fun_list)])
eval(string, {"__builtins__":None}, math_fun_dict)
这样确实解决了安全问题,但是试试输入以下字符:
[c for c in ().__class__.__bases__[0].__subclasses__() if c.__name__ == 'Quitter'][0](0)()
# ().__class__.__bases__[0].__subclasses__()显示object类的所有子类,类Quitter与“quite”功能绑定,因此上面的输入会直接导致程序退出。
因此在实际应用过程中,如果使用对象不是信任源,应该尽量避免使用eval,在需要使用eval的地方可以用安全性更好的ast.literal_eval替代。
建议十四:使用enumerate()获取序列迭代的索引和值
函数enumerate()主要是为了解决在循环中获取索引以及对应值的问题,它具有一定的惰性,每次仅在需要的时候才会产生一个(index,item)对。使用如下:
enumerate(sequence, start=0)
#sequence可以是list、 set等任何迭代对象
#默认从0开始
#函数返回一个迭代器,可以使用next()方法获取下一个元素
建议十五:分清 == 与 is 的使用场景
is表示的是对象标识符(object identity),即比较两个对象在内存中是否拥有同一块内存空间,而==表示的意思是相等(equal),用来检验两个对象的值是否相等。
还有需要注意的是,在python中有string interning(字符串驻留)机制:对于较小的字符串,为了提高系统性能会保留其值的一个副本,当创建新的字符串的时候直接指向该副本即可。而长字符串不会驻留。