0

I would like to add the "i" for loop variable with a variabel name.

def get_or_refresh_call_list(self, event=None): 
            
    #get dates
    call_dates_webElements = self.get_elements(self.call_dates)
        
    for i in range(len(call_dates_webElements)):
                
        temp_var = 'self.date_label_call_' + f"{i}"
        temp_var.config(text=call_dates_webElements[i].text)

The first variable name would be self.date_label_call_1 and the second would be ' self.date_label_call_2 and so on.

The error I get is: AttributeError: 'str' object has no attribute 'config'

Michael S.
  • 3,050
  • 4
  • 19
  • 34
AppCreator
  • 241
  • 1
  • 2
  • 11
  • Try `temp_var = eval(f'self.date_label_call_{i+1}')` instead. Note that `{i+1}` is used because your variable names start from `_1`. – acw1668 Aug 17 '22 at 08:17
  • Using `eval` is dangerous, but you can use `setattr` instead: `setattr(self, f"date_label_call_{i+1}", "")` – joanis Aug 17 '22 at 14:05
  • 2
    This is a bad practice. Instead of computing dynamic variable names, your code will be much easier to write and debug if you store your data in a dictionary. See [How do I create variable variables](https://stackoverflow.com/questions/1373164/how-do-i-create-variable-variables) – Bryan Oakley Aug 17 '22 at 14:16
  • Although I answered the question as asked, I fully agree with you @BryanOakley. A dict, or maybe a list in this case, would be a much better design for this problem. – joanis Aug 17 '22 at 14:18

2 Answers2

1

The best way to set attributes inside a class when you need to construct their name on the fly is to use setattr. That's exactly what it's for. And later, if you want to read the attribute values in a similar programmatic way, use getattr.

In your code, that means:

    for i in range(len(call_dates_webElements)):
        temp_var = 'date_label_call_' + f"{i+1}"
        temp_text = call_dates_webElements[i].text
        setattr(self, temp_var, temp_text)

or just

    for i in range(len(call_dates_webElements)):
        setattr(self, f"date_label_call_{i+1}", call_dates_webElements[i].text)

Notes:

  • I'm using i+1 for the variable name: as @acw1668 pointed out in the comment, your loop will start at 0, but in the question you say you want your variables to start at _1.
  • I removed self. from temp_var: setattr will already add the attribute to self, so I just need to provide the attribute name.
  • You can later access these attributes as self.date_label_call_1 if you want to hardcode the name, or with getattr(self, f"date_label_call_{i+1}") in a loop over i`.
  • That getattr call will raise an exception if the attribute has not been set before, but you can give it a default value to return instead when the attribute is not defined, e.g., getattr(self, f"date_label_call_{i+1}", "no such date label call found").
joanis
  • 10,635
  • 14
  • 30
  • 40
0

It’s due to you calling the config function on the string data type temp_var:

temp_var.config(text=call_dates_webElements[i].text)
Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77