在类属性和实例属性之间混淆

时间:2013-02-20 06:30:02

标签: python django

假设我有这个django模型

class Article(object):
       title = models.CharField(max_length=320)
       body  = models.CharField(max_length=320)
       def __init__(self):
              setattr(Article,"user",get_logged_username())

那只是示例代码

我只是想知道,因为我正在设置class属性而不是实例属性所以我的每个用户都会有相同的user属性

最初它是john然后是其他人的浏览器并点击添加新文章

然后如果我检查我的user那么它的用户名是否相同

4 个答案:

答案 0 :(得分:0)

您在这里设置属性,因为Article是一个类。

这意味着您的所有实例都将共享此属性:

>>> class Article(object):
...     def __init__(self, user):
...         Article.user = user
...         

>>> article_john = Article('John')
>>> article_elli = Article('Ellie')                                                 

>>> article_john.user  # Modified by the second Article creation!
'Ellie'

但请注意,对象(实例)可以拥有自己的user属性,该属性会覆盖类属性:

>>> article_john.user = 'This was initially John'
>>> article_ellie.user  # Unmodified, because it access the class attribute Article.user
'Ellie'

每个实例属性只需使用self.user = get_logged_username()设置。

答案 1 :(得分:0)

看起来您想要设置实例属性,而不是类属性。

setattr(self,"user",get_logged_username())

或者...

this.user = get_logged_username()

如果您希望该类的所有实例最初具有name属性john,请在声明该类时进行制作。

class Article:
    name = 'john'

答案 2 :(得分:0)

请注意,每个新实例的创建都会将类属性user置于相同的值:

class Article(object):
       title = '111'
       body  = '222'
       def __init__(self):
              setattr(Article,"user",145)

aaaaaaa = Article()
print '# aaaaaaa = Article()  /done'
print '  aaaaaaa.__dict__ == %r ' % aaaaaaa.__dict__
print '  aaaaaaa.user == %r ' % aaaaaaa.user
print '  Article.user == %r\n' % Article.user

aaaaaaa.user = 2000
print '# aaaaaaa.user = 2000  /done'
print '  aaaaaaa.__dict__ == %r ' % aaaaaaa.__dict__
print '  aaaaaaa.user == %r ' % aaaaaaa.user
print '  Article.user == %r\n' % Article.user

Article.user = 'JUJU'
print "# Article.user = 'JUJU'  /done"
print '  aaaaaaa.__dict__ == %r ' % aaaaaaa.__dict__
print '  aaaaaaa.user == %r ' % aaaaaaa.user
print '  Article.user == %r\n' % Article.user

bbbbbbb = Article()
print '# bbbbbbb = Article()  /done'
print '  aaaaaaa.__dict__ == %r ' % aaaaaaa.__dict__
print '  aaaaaaa.user == %r ' % aaaaaaa.user
print '    bbbbbbb.__dict__ == %r ' % bbbbbbb.__dict__
print '    bbbbbbb.user == %r ' % bbbbbbb.user
print '    Article.user == %r ' % Article.user

结果

# aaaaaaa = Article()  /done
  aaaaaaa.__dict__ == {} 
  aaaaaaa.user == 145 
  Article.user == 145

# aaaaaaa.user = 2000  /done
  aaaaaaa.__dict__ == {'user': 2000} 
  aaaaaaa.user == 2000 
  Article.user == 145

# Article.user = 'JUJU'  /done
  aaaaaaa.__dict__ == {'user': 2000} 
  aaaaaaa.user == 2000 
  Article.user == 'JUJU'

# bbbbbbb = Article()  /done
  aaaaaaa.__dict__ == {'user': 2000} 
  aaaaaaa.user == 2000 
    bbbbbbb.__dict__ == {} 
    bbbbbbb.user == 145 
    Article.user == 145

答案 3 :(得分:0)

设置类属性时,您可能希望将自己限制为将在该类的多个或所有实例之间共享的对象。对于将更改或对每个实例唯一的值,请在 init ()方法中设置它们。

例如,您可能有一个在创建实例时使用的threading.Lock实例,然后是一个将用于每个实例同步任务的每个实例的threading.Lock。

class Article:
    creation = threading.Lock
    count = 0

    def __init__ (self):
        Article.creation.acquire ()

        self.id = Article.count
        self.lock = threading.Lock

        Article.count += 1
        Article.creation.release ()


    def critical (self):
        self.lock.acquire ()

        # Something sensitive happens here.

        self.lock.release ()

要回到原来的问题,您可能需要:

class Article(object):

   def __init__(self):
       self.title = models.CharField(max_length=320)
       self.body  = models.CharField(max_length=320)
       self.user  = get_logged_username()