在对象的__class__属性上设置属性

时间:2014-03-04 10:30:50

标签: python django

我对设置对象的属性和在对象的__class__属性上设置属性之间的区别感到困惑。粗略地,obj.attr vs obj.__class__.attr。它们之间有什么区别?

前者是否在实例上设置属性,而后者在实例的类上设置属性(使该属性可用于所有实例)?如果是这种情况,那么Django请求中的这些新类属性如何可用,因为该框架适用于多个线程?设置类变量是否会使它在请求之间保持不变?

2 个答案:

答案 0 :(得分:3)

是的,那是在课堂上设置属性。但不,这不一定会在请求之间提供,尽管它可能会。

您的问题显示了对Django请求如何工作的误解。 Django不一定使用多个线程:事实上,在大多数服务器配置中,它由服务器管理的多个独立进程托管。同样,根据配置,每个进程可能有也可能没有多个线程。但无论是否涉及线程,进程都会始终由服务器启动和终止。

如果您在一次请求期间在Django中的类或模块上设置了属性,那么由同一进程提供的任何后续请求都将看到该属性。但是无法保证您的下一个请求将由哪个流程提供服务。并且当然无法知道同一用户是否将从同一进程访问下一个请求。

在类或模块级别设置东西可能是一些非常讨厌的线程安全错误的来源。我的建议一般不是这样做的。如果您需要将请求保留在请求中,请将其存储在数据库,缓存中,或者(特别是如果它特定于特定用户)在会话中。

答案 1 :(得分:1)

详细说明Python方面......

obj.attr正在寻找实例属性,obj.__class__.attr专门寻找类属性。

请注意,如果您调用obj.attr来查找实例属性,但Python无法找到具有该名称的实例属性,则会在基类中查找类属性。

>>> 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"

现在,您可以使用相同名称的实例属性和类属性。