Search code examples
python-3.xclassinitializationgetter-setter

AttributeError: <Class> object has no attribute outside loop?


I have a class called state_class:

class state_class:
  def __init__(self, state_name): 

    self.state_name = state_name

    @property
    def state_col(self):
        """state_col getter"""
        return self._state_col

    @state_col.setter
    def state_col(self):
        """state_col setter"""
        self._state_col = state_col

I initiate this class inside a an if statement and for loop:

for region in regions:
  if region == '1':
    for region in regions:
        for col in range(prelim_sheet.ncols):
          if (prelim_sheet.cell_value(0, col) == r.region_name):
           ...
          else:
            for state in state_list:
                if state.strip() == 'NewHampshire':  
                    s = state_class(state)
                    if ((prelim_sheet.cell_value(0, col)).replace(" ", "") == s.state_name):
                        s.state_col = col
                        print(s.state_col)
                        ...

As you can see, at the bottom, I have a print statement for s.state_col, which print out the correct value. But if I try to call s.state_col outside of the if and for loops, I get an error:

AttributeError Traceback (most recent call last) in ----> 1 s.state_col

AttributeError: 'state_class' object has no attribute 'state_col'

I have tested this outside the loops and it works fine:

s = state_class('NewHampshire')
col = 20
s.state_col = col
print(s.state)
>>> 20

Is there a reason why it set state_col inside the loop or let me call it outside? How can I resolve this?


Solution

  • As @Eli Korvigo said, you should initialize all variables in the init function of a class, otherwise they do not exist until you set them.

    edit:

    I looked closer to your code and the indenting was incorrect, and the setter function requires an input. Less important, class names should be CamelCase. This code should now work:

    class StateClass:
        def __init__(self, state_name):
            self.state_name = state_name
            self._state_col = None
    
        @property
        def state_col(self):
            """state_col getter"""
            return self._state_col
    
        @state_col.setter
        def state_col(self, s):
            """state_col setter"""
            self._state_col = s