Class attributes in Python

允我心安 提交于 2019-12-13 06:53:04

问题


Is there any difference in the following two pieces of code? If not, is one preferred over the other? Why would we be allowed to create class attributes dynamically?

Snippet 1

class Test(object):
    def setClassAttribute(self):
        Test.classAttribute = "Class Attribute"

Test().setClassAttribute()

Snippet 2

class Test(object):
    classAttribute = "Class Attribute"

Test()

回答1:


It's more natural to do it like #2, but notice that they do different things. With #2, the class always has the attribute. With #1, it won't have the attribute until you call setClassAttribute.

You asked, "Why would we be allowed to create class attributes dynamically?" With Python, the question often is not "why would we be allowed to", but "why should we be prevented?" A class is an object like any other, it has attributes. Objects (generally) can get new attributes at any time. There's no reason to make a class be an exception to that rule.




回答2:


First, setting a class attribute on an instance method is a weird thing to do. And ignoring the self parameter and going right to Test is another weird thing to do, unless you specifically want all subclasses to share a single value.*

* If you did specifically want all subclasses to share a single value, I'd make it a @staticmethod with no params (and set it on Test). But in that case it isn't even really being used as a class attribute, and might work better as a module global, with a free function to set it.

So, even if you wanted to go with the first version, I'd write it like this:

class Test(object):
    @classmethod
    def setClassAttribute(cls):
        cls.classAttribute = "Class Attribute"

Test.setClassAttribute()

However, all that being said, I think the second is far more pythonic. Here are the considerations:

  • In general, getters and setters are strongly discouraged in Python.
  • The first one leaves a gap during which the class exists but has no attribute.
  • Simple is better than complex.

The one thing to keep in mind is that part of the reason getters and setters are unnecessary in Python is that you can always replace an attribute with a @property if you later need it to be computed, validated, etc. With a class attribute, that's not quite as perfect a solution—but it's usually good enough.


One last thing: class attributes (and class methods, except for alternate constructor) are often a sign of a non-pythonic design at a higher level. Not always, of course, but often enough that it's worth explaining out loud why you think you need a class attribute and making sure it makes sense. (And if you've ever programmed in a language whose idioms make extensive use of class attributes—especially if it's Java—go find someone who's never used Java and try to explain it to him.)




回答3:


I think #2 feels more natural. #1's implementation means that the attribute doesn't get set until an actual instance of the class gets created, which to me seems counterintuitive to what a class attribute (vs. object attribute) should be.



来源:https://stackoverflow.com/questions/27257379/class-attributes-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!