Search code examples
pythonattributeerror

Python: AttributeError when checking if properties exist


I have a logging class that allows a prefix to be added to the logs. If there is no prefix given, it should default to "".

class PrefixedLog(Loggable):
    def __init__(self):
        self._prefix = None

    @property
    def prefix(self):
        if self._prefix:
            return self._prefix
        else:
            return ""

    @prefix.setter
    def prefix(self, value):
        self._prefix = value

    @property
    def log(self):
        if not hasattr(self, '_log') or not self._log:
            log = logging.getLogger(self.__class__.__name__)
            self._log = LoggerAdapter(self._prefix, log)
        return self._log

I have another class, which then creates an object of another class where I'm trying to set the prefix:

class A(PrefixedLog):
    def __init__(self, **kwargs):
        super(A, self).__init__(**kwargs)
        self.b = B()

The class with the prefix:

class B(PrefixedLog):
    self.another_class = AnotherClass()
    if self.prefix:
        self.another_class.prefix = 'desired prefix'

I'm getting this error:

AttributeError: 'B' object has no attribute '_prefix'

on the

if self.prefix: 

line.

I've searched for solutions already but most had to do with formatting issues...I've made sure there are no tabs. Any ideas on what the problem might be? Thanks in advance.

Also - I want to make sure that even if a class doesn't specifically set a prefix, then the prefix does default to "" without any errors, ie I don't have to go back to every class I have and set the prefix.


Solution

  • When you write self._prefix it retrieves the value of the attribute, if the attribute doesn't exist it raises an AttributeError. In this case you want to be checking whether the attribute exists or not which is what hasattr is for:

    if hasattr(self,"_prefix"):
        return self._prefix
    else:
        return ''
    

    However this can be shortened with a fallback value for getattr

    return getattr(self,"_prefix", '')