Python “setattr”(和“getattr”)的使用会被视为坏习惯吗?
Python “setattr”(和“getattr”)的使用会被视为坏习惯吗?,python,getattr,setattr,Python,Getattr,Setattr,setattr和getattr某种程度上进入了我的编程风格(主要是科学方面的东西,我对python的知识是自述的) 考虑到exec和eval继承了潜在的危险,因为在某些情况下它们可能会导致安全问题,我想知道对于setattr来说,相同的参数是否有效。(关于getattr我发现其中包含一些信息——尽管论证不是很有说服力。) 据我所知,setattr可以不用太担心就可以使用,但老实说,我并不相信我的python知识,如果我错了,我想尝试摆脱使用setattr的习惯 非常感谢您的任何意见 首先,它肯定
setattr
和getattr
某种程度上进入了我的编程风格(主要是科学方面的东西,我对python的知识是自述的)
考虑到exec
和eval
继承了潜在的危险,因为在某些情况下它们可能会导致安全问题,我想知道对于setattr
来说,相同的参数是否有效。(关于getattr
我发现其中包含一些信息——尽管论证不是很有说服力。)
据我所知,setattr
可以不用太担心就可以使用,但老实说,我并不相信我的python知识,如果我错了,我想尝试摆脱使用setattr
的习惯
非常感谢您的任何意见 首先,它肯定会使现有的安全漏洞更容易被发现 例如,假设您的代码执行
exec
、eval
、SQL查询或通过字符串格式构建的URL等,并且假设您正在向格式化命令或作为eval
上下文或任何内容传递,例如,locals()
或过滤后的dict
。使用setattr
显然会扩大安全漏洞,使我更容易找到攻击代码的方法,因为您无法再确定要传递给这些函数的内容
但是如果你不做其他不安全的事情呢?那么setattr
安全吗
没那么糟,但还是不安全。如果我可以影响正在设置的属性的名称,例如,我可以替换对象上我想要的任何方法
您可以尝试对此进行保护,例如,首先检查旧值是否不可调用,或者是否不是方法类型描述符,等等。同样,您可以尝试防止人们在eval
中调用函数,或在SQL参数中添加引号和分号等。这实际上与其他任何情况相同。而且,试图关闭通往敞开大门的所有非法通道要比一开始就不开门困难得多
如果名称从未来自任何可能受用户影响的内容,该怎么办
那么,既然如此,为什么要使用setattr
?没有充分的理由使用文本调用setattr
无论如何,当Lattyware说通常有更好的方法来解决手头的问题时,他几乎肯定是在谈论可读性、可维护性和惯用性。但是,使用这些更好的方法的副作用是,您还经常避免任何安全隐患
90%的情况下,解决方案是使用dict
而不是对象。与Javascript不同,它们在Python中不是同一件事,也不应该以相同的方式使用它们。dict
没有方法、继承或内置特殊名称,因此您不必担心这些。它还有一个更方便的语法,可以说d['foo']
,而不是setattr(o,'foo')
。而且可能效率更高。等等但归根结底,使用dict的原因是概念上的原因:dict是一个命名的值集合;类实例是模型空间对象的表示形式,它们不是一回事
那么,为什么setattr
甚至存在呢
它存在的基本原因与其他低级功能相同,比如能够访问im\u func
或func\u closure
,或者拥有traceback
和imp
等模块,或者像对待任何其他方法一样对待特殊方法,或者就此而言exec
和eval
首先,您可以使用这些低级工具构建更高级的东西。例如,要构建集合.namedtuple
,您需要exec
或setattr
其次,您偶尔需要在运行时修改补丁代码,因为您无法在编译时修改它(甚至可能无法看到它),而像setattr
这样的工具可能是实现这一点的关键
与eval
非常相似的setattr
功能经常被来自Javascript、Tcl或其他一些语言的人误用。但只要它能被用来做好事,你就不想把它从语言中去掉。(TOOWTDI不应该被字面理解为只能编写一个程序。)
但这并不意味着你应该尽可能地到处使用这些东西。您不会编写
mylist.\uuu getitem\uuuu(切片(1,10,2))
而不是mylist[1:10:2]
。有时,可以直接调用<代码>、ygGeTimeTys或生成<代码> Studio对象,这是使代码的其余部分更为python的方法的基础,或者是本地化工作方式以避免感染其他代码。否则,会有更清晰、更简单的方法来解决问题。这取决于,这不是天生的邪恶,但通常会有更好的方法来解决手头的问题。@Lattyware在哪种意义上更好?更安全、更短、更简洁?你能说得更准确些吗?你是否担心“可利用的安全风险”中的“危险”或“可读性较差的代码”?我很确定Lattyware的意思是“更可读、更易维护、更习惯”,而不是更简短或更简洁,因为几乎没有人关心或应该关心后者。(“安全”是一个完全不同的问题,人们会关心,也应该关心。这就是我要求澄清的原因。)@abarnert可读性其实并不重要(至少对于这个精确的问题不是这样)。这是关于安全风险的。我认为关于getattr
的链接问题与每个人谈论的都是性能,而不是安全性无关。我可以在您的对象上替换我想要的任何方法。