2017-09-01 152 views
-2

我遇到了一個非常奇怪的問題。奇怪的python對象屬性錯誤

請參閱下面的代碼。在這個類中有一個像所有其他屬性一樣定義的屬性「怪異」。 (問題區域由

========================

標記代碼的========== ==============)

但是,當我訓練去訪問它的一個函數時,它會引發一個錯誤,說該屬性不存在。

但是如果我刪除行訪問的功能屬性,然後創建一個對象,該對象的該屬性可以被訪問......

可否請你看看代碼,看看是什麼是哪裏錯了,我在我束手無策這裏...:'(

class img_iter(DataIter): 
    def __init__(self, dir_train, 
      dir_label, 
      data_name = "data", 
      label_name = "softmax_label", 
      last_batch_handle = 'pad', 
      batch_size = 1, 
      #=================================================== 
      #=================================================== 
      color_mean = (117, 117, 117), 
      #=================================================== 
      #=================================================== 
      cut_off_size = None): 
     super().__init__() 
     # directories as attributes 
     self.dir_train = dir_train 
     self.dir_label = dir_label 
     # names 
     self.data_name = data_name 
     self.label_name = label_name 
     # read data and label files into list 
     self.img_data_lst = [s for s in os.listdir(dir_train) if '.jpg' in s] 
     self.img_data_iter = iter(self.img_data_lst) 
     if self.dir_label is not None: 
      self.img_label_lst = [s for s in os.listdir(dir_label) if '.gif' in s] 
     # number of data files 
     self.num_data = len(self.img_data_lst) 
     # read data when initialising 
     self.data, self.label = self._read() 
     # size limiter 
     self.cut_off_size = cut_off_size 
     # batch size 
     self.batch_size = batch_size 
     # data cursor 
     self.cursor = -batch_size 
     #=================================================== 
     #=================================================== 
     self.weird = np.array(color_mean) 
     #=================================================== 
     #=================================================== 
     self.last_batch_handle = last_batch_handle 

    def _read(self): 
     """get two list, each list contains two elements: name and nd.array 
value""" 
     data = {} 
     label = {} 
     data[self.data_name], label[self.label_name] = self._read_img() 
     return list(data.items()), list(label.items()) 

    def _read_img(self): 
     # get next data file from the file name iterator 
     img_name = self.img_data_iter.__next__() 
     # open image file 
     img = Image.open(os.path.join(self.dir_train, img_name)) 
     # find corresponding label image and open  [s for s in self.img_label_lst if img_name in s][0] 
     label_name = img_name.split('.')[0] + '_mask.gif' 
     label = Image.open(os.path.join(self.dir_label, label_name)) 
     # check image file size match 
     assert img.size == label.size 
     # convert into numpy array and manipulate, resulting 3d array: height, width, color 
     img = np.array(img, dtype = np.float32) 
     #=================================================== 
     #=================================================== 
     #img = img - self.weird.reshape(1,1,3) 
     test = self.weird 
     #=================================================== 
     #=================================================== 
     img = np.swapaxes(img, 0, 2) 
     # (c, h, w) 
     img = np.swapaxes(img, 1, 2) 
     # (1, c, h, w) 
     img = np.expand_dims(img, axis=0) 
     # resulting 2d array: height, width 
     label = np.array(label) 
     # (h, w) 
     label = np.array(label) 
     # (1, h, w) 
     label = np.expand_dims(label, axis=0) 
     return (img, label) 

    def reset(self): 
     self.cursor = -1 
     self.img_data_iter = iter(self.img_data_lst) 

    def iter_next(self): 
     self.cursor += 1 
     if (self.cursor < self.num_data - 1): 
      return True 
     else: 
      return False 

    def next(self): 
     if self.iter_next(): 
      ''' 
      try: 
       self.data, self.label = self._read() 
       return {self.data_name : self.data[0][1], 
         self.label_name : self.label[0][1]} 
      except: 
       raise 
      ''' 
      self.data, self.label = self._read() 
      return DataBatch(data = self.data, label = self.label, \ 
        pad=self.getpad(), index=None) 
     else: 
      raise StopIteration 

    @property 
    def provide_data(self): 
     """The name and shape of data provided by this iterator""" 
     return [(k, tuple([1] + list(v.shape[1:]))) for k, v in self.data] 

    @property 
    def provide_label(self): 
     """The name and shape of label provided by this iterator""" 
     return [(k, tuple([1] + list(v.shape[1:]))) for k, v in self.label] 

    def get_batch_size(self): 
     return 1 

截圖:

與調用該函數的類屬性 with call to the class attribute in the function

移除對類屬性的調用,創建一個對象並直接訪問相同的屬性。

remove call to the class attribute, create an object and access the same attribte directly

+0

嗨,它不是一個雙縮進,雖然它看起來這樣。我只是爲了更好的可讀性而對齊這些參數。 –

+0

我誤讀了,道歉 – asongtoruin

+0

@ Y.L讓我建議你將其修剪爲[mcve],並將文字發佈爲文字,而不是圖片。 – Goyo

回答

0

您試圖訪問self.weird定義之前。

self.data, self.label = self._read() 
# self._read() calls self. _read_img() 
# which tries to access self.weird 
# => AttributeError... 

#...  

# move this line above `self.data...`, 
# and all should be well! 
self.weird = np.array(color_mean) 

希望這有助於!

相關問題