2

I am encountering a strange problem that relates to instance attributes. I have a variable logger, which I want to be an instance attribute. However, I get the error AttributeError: can't set attribute unless I move the attribute logger outside the __init__() function, which (IIRC), means that I am declaring logger as a class attribute (not what I want).

Here is a snippet of my code:

class MyScraper(ABC,scrapy.Spider):
    """Abstract base class for scraping non JS Web pages"""
    #logger = None    # Commented out, as I don't want class instance

    def __init__(self, *args, **kwargs): 
        self.connection = None
        self.channel = None
        self.topic = None            

        log_format = "%(asctime)s - %(levelname)s - %(message)s"
        log_level = 10
        handler = TimedRotatingFileHandler("{0}.log".format(kwargs['log_filename']), when="midnight", interval=1)
        handler.setLevel(log_level)
        formatter = logging.Formatter(log_format)
        handler.setFormatter(formatter)

        # add a suffix which you want
        handler.suffix = "%Y%m%d"

        #need to change the extMatch variable to match the suffix for it
        handler.extMatch = re.compile(r"^\d{8}$") 

        self.logger = logging.getLogger('my_logger') # <- barfs here

        # finally add handler to logger    
        self.logger.addHandler(handler)   

        # Set up messaging infrastructure ...

Why am I getting this error, and how to fix it?

3
  • Did you create a get-function for self.logger? That might be a reason you cannot set it (without using a set-funtion that is). Commented Oct 19, 2017 at 12:34
  • @mrCarnivore (nice user name BTW!). I don't understand your question. I have other instance variables in my code, and the only one that raises this AttributeError exception is the logger variable, Commented Oct 19, 2017 at 12:38
  • @property def logger(self): return logging.getLogger('my_logger') (like in the answer below) would be a "get-function". With this you make a variable read-only. And therfore causing the error message (thanks for the user-name comment! :-) ) Commented Oct 19, 2017 at 12:41

1 Answer 1

2

If you look at the source code (or even if you just print(scrapy.Spider.logger) you can see that Spider.logger is a property, and in particular without a setter defined, so you can't easily assign to it.

You don't necessarily need to create your own logger if you want to add additional handlers though, so I'm not sure what you're trying to achieve beyond that. Though if you ''really'' wanted to override the default self.logger, since you're subclassing Spider there's nothing stopping you from adding something like:

@property
def logger(self):
    return logging.getLogger('my_logger')

to your class.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks, i also forgot that when i use @property then i need to move the self.variable to self._variable ... so i needed to assign object._variable = "x" and not object.variable = "x" ..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.