Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two ways to declare instance variables in Python? [duplicate]

Is there any difference in functionality and what happens behind the scenes between

class Class:
    def __init__(self, var1):
        self.var1 = var1

and

class Class:
    var1 = ""
    def __init__(self, var1):
        self.var1 = var1

in Python?

like image 430
Rohan Avatar asked Dec 08 '22 00:12

Rohan


2 Answers

Let's explore a bit. This is your class:

class Class:
    var1 = 'in class'
    def __init__(self, var1):
        self.var1 = var1

c = Class('in inst')

Accessing c.var1 shows the var1 from the instance:

>>> c.var1
'in inst'

It is located inside __dict__ of c:

>>> c.__dict__
{'var1': 'in inst'}

The class variable var1 is in __dict__ of Class:

>>> Class.__dict__['var1']
'in class'

Now make a class with only a class variable:

class Class2:
    var1 = 'in class'

c2 = Class2()

Since there is nothing in the instance, var1 from the class will be used:

>>> c2.var1
'in class'

The __dict__ of c2 is empty:

>>> c2.__dict__
{}

Python always looks for var1 first in the instance and than falls back to the class.

like image 101
Mike Müller Avatar answered Dec 28 '22 06:12

Mike Müller


As I pointed out in comment, the Class.var1 is a shared variable. It could be accessed for each instance as self.var1 if you don't erase it with a non-shared variable in __init__. Here is a sample of what happens :

class Test(object):
    shared = 0
    def __init__(self, i):
        self.notshared = i
    def intro(self):
        print("Shared is " + str(self.shared))
        print("NotShared is " + str(self.notshared))

test1 = Test(4)

test1.intro()
# Shared is 0
# NotShared is 4

Test.shared = 5
test1.intro()
# Shared is 5
# NotShared is 4

test2 = Test(3)
test2.intro()
# Shared is 5
# NotShared is 3

Be aware however that if you write the self.shared variable afterwards, you do not access the shared variable with self.shared anymore:

test1.shared = 12
test1.intro()
# Shared is 12
# NotShared is 4
test2.intro()
# Shared is 5
# NotShared is 3
like image 40
DainDwarf Avatar answered Dec 28 '22 06:12

DainDwarf