1

I am a bit confused over the difference between setting an object's attribute and setting an attribute on an object's __class__ attribute. Roughly, obj.attr vs obj.__class__.attr. What's the difference between them?

Is the former setting an attribute on an instance and the latter setting an attribute on an instance's class (making that attribute available to all instances)? If this is the case, then how are these new class attributes available in Django requests, since the framework works with multiple threads? Does setting a class variable make it persist between requests?

asked Mar 4, 2014 at 10:30

2 Answers 2

3

Yes, that is setting the attribute on the class. But no, that would not necessarily make it available between requests, although it might.

Your question shows a misunderstanding of how Django requests work. Django is not necessarily served using multiple threads: in fact, in most server configuration, it is hosted by multiple independent processes that are managed by the server. Again, depending on the configuration, each of those processes may or may not have multiple threads. But whether or not threads are involved, processes are started and killed by the server all the time.

If you set an attribute on a class or module in Django during one request, any subsequent requests served by that same process will see that attribute. But there's no way to guarantee which process your next request will be served by. And there's certainly no way to know if the same user will be accessing the next request from that same process.

Setting things at class or module level can be the source of some very nasty thread-safety bugs. My advice is generally not to do it. If you need to keep things across request, store it in the database, the cache, or (especially if it's specific to a particular user) in the session.

answered Mar 4, 2014 at 10:41
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for your very detailed answer. Indeed, I have some things unclear about requests in Django :). I've recently stumbled upon the following within Django CMS: request.__class__.current_page = LazyPage(). Why does the current_page attribute need to be store on the class and not the instance? Does this guarantee that each request will have its own current_page?
I guess it depends what LazyPage is. I haven't used django-cms - can you point me to the relevant code?
That's a descriptor, which are usually defined on the class. See the Python docs for more information on descriptors. Note, though, that code isn't properly thread-safe, and it has been changed in the most recent version (see github.com/divio/django-cms/blob/develop/cms/middleware/page.py) for precisely that reason.
Alright. And that code isn't thread-safe exactly because the current page is stored per request class, which does not guarantee that each current page stays with its proper request, right? The changed code reflects the idea that the current page must stay with its request object.
1

To elaborate on the Python side...

obj.attr is looking for instance attributes and obj.__class__.attr is specifically looking for class attributes.

Note that if you call obj.attr to find an instance attribute, but Python can't find an instance attribute with that name, it then looks in the baseclass for class attributes.

>>> class MyClass():
 foo = "bar"
>>> a = MyClass()
>>> a.foo # class attribute as no instance attribute foo
"bar"
>>> a.foo = "hello" # you are creating a new instance attribute
>>> a.__class__.foo = "goodbye" # you are re-asisgning the value of the class attrribute
>>> a.foo
"hello"
>>> a.__class__.foo
"goodbye"

So now you can have instance attributes and class attributes with the same names.

answered Mar 4, 2014 at 11:03

Comments

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.