Tim
Tim

Reputation: 99408

How to specify a variable as a member variables of a class or of an instance of the class?

in latest Python 2.7.x:

  1. Given any member variable inside the definition of a class, is the member variable always at the class level in the sense that it is a single variable shared by all the instances of the class?

  2. In the definition of a class, how can I specify

    • which member variables in the definition of a class belong to the class and thus shared by all the instances of the class, and
    • which belong to a particular instance of the class and not to another instance of the class?
  3. How can I refer to a member variable of a class?

    How can I refer to a member variable of an instance of a class?

  4. Do the answers to the above questions appear somewhere in the official python language reference https://docs.python.org/2/reference/? I can't find them there.

Thanks.

Upvotes: 2

Views: 100

Answers (1)

wim
wim

Reputation: 362497

You might want to use the terminology "class variable" and "instance variable" here, as that's the usual language in python.

class Foo(object):

    var1 = "I'm a class variable"

    def __init__(self, var2):
        self.var2 = var2  # var2 is an instance variable

The only scoping rule you really need to know in python is the lookup order for names - "LEGB", for Local, Enclosing, Global and Builtin.

The class scoped variable var1 still has to be looked up by "get attribute", you can only access that by Foo.var1 or self.var1. Of course, you can also access it elsewhere inside the class definition block, but that is just an example usage from the "Local" scope.

When you see self.var1, you can't immediately know whether it is an instance or a class variable (nor, in fact, if the name is bound to an object at all!). You only know that get attribute is tried on the object itself before it's tried on the class.

Indeed, an instance variable can shadow a class variable of the same name:

>>> f1 = Foo(var2='f1_2')
>>> f2 = Foo(var2='f2_2')
>>> f2.var1
"I'm a class variable"
>>> f2.var1 = "Boom!"  # this shadows the class variable
>>> f1.var1, Foo.var1, f2.var1  # but: the class variable still exists
("I'm a class variable", "I'm a class variable", 'Boom!')
>>> del f2.var1  # restores the name resolution on the Foo object
>>> f2.var1
"I'm a class variable"

To complicate matters, we can write fancy code which makes class variables behave more like instance variables; a notable example are "fields" of an ORM. For example in Django, you may define an integer field on the model class - however when you lookup that name on an instance of the model, you get an actual integer returned (not an IntegerField object).

If you're interested in this advanced usage of attribute access, read up on the descriptor protocol. For mundane classes you can safely ignore those details, but it's worth knowing that the usual resolution of instance variables and then class variables has lower precedence than any descriptors that may have been defined on the class.

Upvotes: 2

Related Questions