python/Pyqt5 - how to avoid eval while using ast and getting ValueError: malformed string in attemt to improve code safety
python/Pyqt5 - how to avoid eval while using ast and getting ValueError: malformed string in attemt to improve code safety
我试图根据使用 ast
的示例 how-to-avoid-eval-in-python-for-string-conversion 来阻止使用 eval
。挑战在于,有许多这样的 self.ch%s_label
需要制作,但它的变量会根据用户在 GUI 中的输入而改变。
我的代码:
import ast ...etc.
....
channel_no += 1
ch_width = eval('self.ch%s_label.frameGeometry().width()' % (channel_no))
当我改成:
ch_width = ast.literal_eval('self.ch%s_label.frameGeometry().width()' % (channel_no))
我会得到错误:
File "c:\python\anac2\lib\ast.py", line 80, in literal_eval
return _convert(node_or_string)
File "c:\python\anac2\lib\ast.py", line 79, in _convert
raise ValueError('malformed string')
ValueError: malformed string
更改代码(使用关闭“”)保留错误:
ch_width = ast.literal_eval("'self.ch%s_label.frameGeometry().width()' % (channel_no)")
还有哪些其他选择...有什么建议吗?
您可以使用 getattr
使用动态构造的属性名称从实例中获取属性:
ch_width = getattr(self, 'ch%s_label' % channel_no).frameGeometry().width()
或者一步一步来:
channel_no = 5
attr_name = 'ch%s_label' % channel_no
attr = getattr(self, attr_name)
ch_width = attr.frameGeometry().width()
以这种方式使用 getattr
还意味着如果对象不具有您期望的属性,您将获得 AttributeError
。
我试图根据使用 ast
的示例 how-to-avoid-eval-in-python-for-string-conversion 来阻止使用 eval
。挑战在于,有许多这样的 self.ch%s_label
需要制作,但它的变量会根据用户在 GUI 中的输入而改变。
我的代码:
import ast ...etc.
....
channel_no += 1
ch_width = eval('self.ch%s_label.frameGeometry().width()' % (channel_no))
当我改成:
ch_width = ast.literal_eval('self.ch%s_label.frameGeometry().width()' % (channel_no))
我会得到错误:
File "c:\python\anac2\lib\ast.py", line 80, in literal_eval return _convert(node_or_string) File "c:\python\anac2\lib\ast.py", line 79, in _convert raise ValueError('malformed string') ValueError: malformed string
更改代码(使用关闭“”)保留错误:
ch_width = ast.literal_eval("'self.ch%s_label.frameGeometry().width()' % (channel_no)")
还有哪些其他选择...有什么建议吗?
您可以使用 getattr
使用动态构造的属性名称从实例中获取属性:
ch_width = getattr(self, 'ch%s_label' % channel_no).frameGeometry().width()
或者一步一步来:
channel_no = 5
attr_name = 'ch%s_label' % channel_no
attr = getattr(self, attr_name)
ch_width = attr.frameGeometry().width()
以这种方式使用 getattr
还意味着如果对象不具有您期望的属性,您将获得 AttributeError
。