{"record":{"id":"8d5befa845df134c","repo":"WZMIAOMIAO/deep-learning-for-image-processing","slug":"object-has-no-attribute-8d5bef","errorCode":null,"errorMessage":"'{}' object has no attribute '{}'","messagePattern":"'(.+?)' object has no attribute '(.+?)'","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"pytorch_segmentation/lraspp/train_utils/distributed_utils.py","lineNumber":142,"sourceCode":"\nclass MetricLogger(object):\n    def __init__(self, delimiter=\"\\t\"):\n        self.meters = defaultdict(SmoothedValue)\n        self.delimiter = delimiter\n\n    def update(self, **kwargs):\n        for k, v in kwargs.items():\n            if isinstance(v, torch.Tensor):\n                v = v.item()\n            assert isinstance(v, (float, int))\n            self.meters[k].update(v)\n\n    def __getattr__(self, attr):\n        if attr in self.meters:\n            return self.meters[attr]\n        if attr in self.__dict__:\n            return self.__dict__[attr]\n        raise AttributeError(\"'{}' object has no attribute '{}'\".format(\n            type(self).__name__, attr))\n\n    def __str__(self):\n        loss_str = []\n        for name, meter in self.meters.items():\n            loss_str.append(\n                \"{}: {}\".format(name, str(meter))\n            )\n        return self.delimiter.join(loss_str)\n\n    def synchronize_between_processes(self):\n        for meter in self.meters.values():\n            meter.synchronize_between_processes()\n\n    def add_meter(self, name, meter):\n        self.meters[name] = meter\n\n    def log_every(self, iterable, print_freq, header=None):","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/WZMIAOMIAO/deep-learning-for-image-processing/blob/1ec3fe6f374fc9969973a61f819de25658595afa/pytorch_segmentation/lraspp/train_utils/distributed_utils.py#L124-L160","documentation":"AttributeError thrown by the SmoothedValue/MeterDictionary-style class's custom __getattr__. When attribute lookup fails on the instance, __getattr__ checks self.meters and self.__dict__; if the name is found in neither, it raises AttributeError naming the class and the missing attribute. This is the standard torch.utils.data distrbuted-utils pattern from maskrcnn-benchmark.","triggerScenarios":"Accessing an attribute like logger.meters['loss'] misspelled (e.g. .los), or accessing a meter key that was never registered via __setattr__ on the MetricLogger before reading it, e.g. calling meter loss without a prior update().","commonSituations":"Typos in training scripts (meterr vs meters), reading a loss key before any training step registered it, or copy-pasting code between projects where the MetricLogger was populated with different meter names.","solutions":["Fix the attribute name typo to match a registered meter key","Ensure the meter was created before access: any use of loss_meter.update(...) registers it via __setattr__","Use getattr(obj, 'attr', default) or check `attr in obj.meters` before access"],"exampleFix":"// before\nmean_loss = torch.stack([m.global_avg for m in metric_logger.meters.values()])\nprint(metric_logger.losss)\n// after\nprint(metric_logger.loss)  # correct meter name registered via metric_logger.loss = SmoothedValue()","handlingStrategy":"validation","validationCode":"if attr not in logger.meters and attr not in logger.__dict__:\n    print(f\"available meters: {list(logger.meters)}\")","typeGuard":"def has_meter(logger, name: str) -> bool:\n    return name in logger.meters or hasattr(logger, name)","tryCatchPattern":"try:\n    value = logger.loss.global_avg\nexcept AttributeError as e:\n    value = float('nan')  # or fall back to default metric","preventionTips":["Register every meter with metric_logger.name = SmoothedValue() before reading","Use IDE autocomplete to avoid typos on MetricLogger attributes","Keep meter names consistent between train and eval loops"],"tags":["python","attributeerror","training-loop"],"backgroundTag":"attribute-not-found","analyzedSha":"1ec3fe6f374fc9969973a61f819de25658595afa","analyzedAt":"2026-08-30T09:19:11.901Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}