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?

Iguananaut
23.8k6 gold badges54 silver badges65 bronze badges
asked Oct 19, 2017 at 12:30
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.

answered Oct 19, 2017 at 12:36
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

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.