python/Pyqt5 - how to avoid eval while using ast a

2019-08-27 08:27发布

问题:

I'm trying to prevent to use eval based on an example how-to-avoid-eval-in-python-for-string-conversion using ast. The challange is that there are a dozen of these self.ch%s_label's to be made but the variable for it changes based on user input in the GUI.

My code:

import ast ...etc.

....

channel_no += 1

ch_width  = eval('self.ch%s_label.frameGeometry().width()' %  (channel_no))

When I change it into:

ch_width  = ast.literal_eval('self.ch%s_label.frameGeometry().width()' %  (channel_no))

I'll get the error:

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

Changing the code (using closing " ") retains the error:

ch_width  = ast.literal_eval("'self.ch%s_label.frameGeometry().width()' %  (channel_no)")

What other options are there... Any suggestions?

回答1:

You could use getattr to get the attribute from the instance using the dynamically constructed attribute name:

ch_width = getattr(self, 'ch%s_label' % channel_no).frameGeometry().width() Or step by step:

channel_no = 5
attr_name = 'ch%s_label' % channel_no
attr = getattr(self, attr_name)
ch_width = attr.frameGeometry().width()

Using getattr in this way also means you get an AttributeError if an object doesn't have the attribute, as you'd expect.