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

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

我有一个 class 叫 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

我在 if 语句和 for 循环中启动此 class:

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)
                        ...

如您所见,在底部,我有一个 s.state_col 的打印语句,它打印出正确的值。但是如果我尝试在 iffor 循环之外调用 s.state_col,我会得到一个错误:

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

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

我已经在循环外测试了它,它工作正常:

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

它在循环内设置 state_col 或让我在循环外调用它有什么原因吗?我该如何解决?

正如@Eli Korvigo 所说,您应该在 class 的 init 函数中初始化所有变量,否则它们在您设置之前不存在。

编辑:

我仔细查看了您的代码,发现缩进不正确,setter 函数需要输入。不太重要的是,class 名称应该是 CamelCase。这段代码现在应该可以工作了:

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

经过多次试验和错误,我确定这个问题的症结不在 state_class getter 和 setter(它们在循环内工作),而是我放在的 else 语句结束。

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)

本质上,这就是说,如果不满足第一个条件,请继续滚动列(大约有 34 列)并且 class 实例化会在此过程中搞砸。 为了解决这个问题,我添加了一些东西。 1) 我更改了 else' to anelif` 语句并设置了一些条件。 2) 我添加了一个动态字典,允许我为每个状态存储 class 的实例(使用 'NewHampshire' 只是为了测试目的)。虽然我认为 @big_bad_bison 的解决方案可能有效(我相信他们),但我的新解决方案实际上是在这种情况下最适合我的解决方案。感谢协助:

    state_map = {}
    for col in range(prelim_sheet.ncols):
        col_name = prelim_sheet.cell_value(0, col)

        if (col_name == region_map[region].region_name):
            region_map[region].region_total_col = col
            region_map[region].detailed_col = region_map[region].region_total_col
            region_map[region].approx_col = region_map[region].region_total_col + 1
            region_map[region].unmapped_col = region_map[region].region_total_col + 2
            region_map[region].total_col = region_map[region].region_total_col + 3


        elif (col_name.replace(" ", "") in region_map[region].region_long_list):
            state = col_name
            state_map[state] = state_class(state)
            state_map[state].state_col = col
            state_map[state].detailed_col = state_map[state].state_col
            state_map[state].approx_col = state_map[state].state_col + 1
            state_map[state].unmapped_col = state_map[state].state_col + 2
            state_map[state].total_col = state_map[state].state_col + 3    
            print("The col is {}".format(str(col)),state_map[state].state_col, state)

        region_map[region].state_map = state_map