Instance variables vs. class variables in Python

后端 未结 4 904
我在风中等你
我在风中等你 2020-11-22 05:32

I have Python classes, of which I need only one instance at runtime, so it would be sufficient to have the attributes only once per class and not per instance. If there woul

4条回答
  •  挽巷
    挽巷 (楼主)
    2020-11-22 06:37

    Further echoing Mike's and Alex's advice and adding my own color...

    Using instance attributes are the typical... the more idiomatic Python. Class attributes are not used used as much, since their use cases are specific. The same is true for static and class methods vs. "normal" methods. They're special constructs addressing specific use cases, else it's code created by an aberrant programmer wanting to show off they know some obscure corner of Python programming.

    Alex mentions in his reply that access will be (a little bit) faster due to one less level of lookup... let me further clarify for those who don't know about how this works yet. It is very similar to variable access -- the search order of which is:

    1. locals
    2. nonlocals
    3. globals
    4. built-ins

    For attribute access, the order is:

    1. instance
    2. class
    3. base classes as determined by the MRO (method resolution order)

    Both techniques work in an "inside-out" manner, meaning the most local objects are checked first, then outer layers are checked in succession.

    In your example above, let's say you're looking up the path attribute. When it encounters a reference like "self.path", Python will look at the instance attributes first for a match. When that fails, it checks the class from which the object was instantiated from. Finally, it will search the base classes. As Alex stated, if your attribute is found in the instance, it doesn't need to look elsewhere, hence your little bit of time savings.

    However, if you insist on class attributes, you need that extra lookup. Or, your other alternative is to refer to the object via the class instead of the instance, e.g., MyController.path instead of self.path. That's a direct lookup which will get around the deferred lookup, but as alex mentions below, it's a global variable, so you lose that bit that you thought you were going to save (unless you create a local reference to the [global] class name).

    The bottom-line is that you should use instance attributes most of the time. However, there will be occasions where a class attribute is the right tool for the job. Code using both at the same time will require the most diligence, because using self will only get you the instance attribute object and shadows access to the class attribute of the same name. In this case, you must use access the attribute by the class name in order to reference it.

提交回复
热议问题