{"record":{"id":"c5e886022aea79a0","repo":"WZMIAOMIAO/deep-learning-for-image-processing","slug":"object-has-no-attribute-c5e886","errorCode":null,"errorMessage":"'{}' object has no attribute '{}'","messagePattern":"'(.+?)' object has no attribute '(.+?)'","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"pytorch_object_detection/faster_rcnn/train_utils/distributed_utils.py","lineNumber":161,"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":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/WZMIAOMIAO/deep-learning-for-image-processing/blob/1ec3fe6f374fc9969973a61f819de25658595afa/pytorch_object_detection/faster_rcnn/train_utils/distributed_utils.py#L143-L179","documentation":"SmoothedValue/MetricLogger implements __getattr__ that looks up `attr` first in self.meters, then in self.__dict__; if found in neither it raises AttributeError. This occurs when accessing a metric/attribute that was never registered or recorded.","triggerScenarios":"Accessing logger.some_metric before any update(some_metric, ...) call registered it in meters; typo in meter name; accessing an instance attribute on the object when __getattr__ intercepts missing attributes.","commonSituations":"Reading loss values from the MetricLogger before the first training iteration; renaming a metric key in one place but not the logging code; pickling issues that bypass meters initialization.","solutions":["Register the meter first via meters[key] = SmoothedValue() or call update(key, value) before accessing it","Print the available keys (logger.meters.keys()) to find the correct attribute name","Fix typos in the attribute/metric name"],"exampleFix":"// before\nprint(logger.loss.global_avg)  # never updated\n// after\nlogger.meters['loss'] = SmoothedValue()\n# or update first:\nlogger.update(loss=loss_value)\nprint(logger.loss.global_avg)","handlingStrategy":"type-guard","validationCode":"attr = \"loss\"\nassert attr in logger.meters or attr in logger.__dict__, f\"{attr} not registered; available: {list(logger.meters)}\"","typeGuard":"def has_meter(logger, attr: str) -> bool:\n    return attr in logger.meters or attr in logger.__dict__","tryCatchPattern":"try:\n    value = logger.loss\nexcept AttributeError as e:\n    value = None\n    print(f\"metric missing: {e}; registered meters: {list(logger.meters)}\")","preventionTips":["Call update(key, value) before reading the meter","List logger.meters.keys() when unsure of metric names","Centralize metric key names in constants to avoid typos"],"tags":["python","attributeerror","logging","metrics"],"backgroundTag":"attribute-not-found","analyzedSha":"1ec3fe6f374fc9969973a61f819de25658595afa","analyzedAt":"2026-08-30T09:19:11.901Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}