Python Forum
Understanding Class Variables - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Understanding Class Variables (/thread-18870.html)



Understanding Class Variables - vindo - Jun-04-2019

Hi,
I am a newbeee to python and had a prior java knowledge.
So, while learning python object oriented concepts, i am trying to relate to java (kinda easy to understand), but sometimes they don't seem to exactly match like in this case.

Here is what i am trying to understand.
Basically i am assuming that the class variables in python are similar to static variables in java.I did find some online explanations stating that class variables of python are similar to static variables in java.
i.e, while these variables are accessible without creation of an instance/object of the class, any change to these variables either through instance/object or class level would have effect in all the other instances of the class as well. At least that is the case in Java.



So i quickly performed the below test and noticed that is not the case in python.
Initially when i changed the value to "Class Name" using the class, all the instances had the same effect. But when i changed the value from an instance they were different (i was expecting all of them to change). Even surprising was the last assignment when i did it from the class level ("Class Name Again"), they were different (while the first time they were all same).

Can you explain Wall

class Customer:
    name = ""
   
customer_1 = Customer()
customer_2 = Customer()
print("")
print("ID of customer 1 ::", id(customer_1))
print("ID of customer 2 ::", id(customer_2))

print("")
print("name of class customer  ::", Customer.name)
print("name of customer 1 ::", customer_1.name)
print("name of customer 2 ::", customer_2.name)

print("")
print("Assigning new name by class ::")
Customer.name = "Class Name"
print("name of class customer  ::", Customer.name)
print("name of customer 1 ::", customer_1.name)
print("name of customer 2 ::", customer_2.name)

print("")
print("Assigning new name by instance 1 ::")
customer_1.name = "Customer 1"
print("name of class customer  ::", Customer.name)
print("name of customer 1 ::", customer_1.name)
print("name of customer 2 ::", customer_2.name)

print("")
print("Assigning new name by instance 2 ::")
customer_2.name = "Customer 2"
print("name of class customer  ::", Customer.name)
print("name of customer 1 ::", customer_1.name)
print("name of customer 2 ::", customer_2.name)

print("")
print("Assigning new name by class ::")
Customer.name = "Class Name Again"
print("name of class customer  ::", Customer.name)
print("name of customer 1 ::", customer_1.name)
print("name of customer 2 ::", customer_2.name)
ID of customer 1 :: 99586960
ID of customer 2 :: 147686456

name of class customer  :: 
name of customer 1 :: 
name of customer 2 :: 

Assigning new name by class ::
name of class customer  :: Class Name
name of customer 1 :: Class Name
name of customer 2 :: Class Name

Assigning new name by instance 1 ::
name of class customer  :: Class Name
name of customer 1 :: Customer 1
name of customer 2 :: Class Name

Assigning new name by instance 2 ::
name of class customer  :: Class Name
name of customer 1 :: Customer 1
name of customer 2 :: Customer 2

Assigning new name by class ::
name of class customer  :: Class Name Again
name of customer 1 :: Customer 1
name of customer 2 :: Customer 2



RE: Understanding Class Variables - Yoriz - Jun-04-2019

Customer.name is a class attribute shared by all instances made from the class.

customer_1.name is an instance attribute unique to the instance


RE: Understanding Class Variables - vindo - Jun-04-2019

(Jun-04-2019, 06:45 PM)Yoriz Wrote: Customer.name is a class attribute shared by all instances made from the class.

customer_1.name is an instance attribute unique to the instance

Based on the first statement.
customer_1 is an instance made from the class "Customer". I was thinking customer_1 shares the same variable "name" of the class "Customer".
Am i missing anything here?


RE: Understanding Class Variables - Yoriz - Jun-04-2019

class Customer:
    name = 'Customer class'

    def __init__(self, name=None):
        if name:
            self.name = name

    def __repr__(self):
        return f'Class name: {Customer.name}, instance name: {self.name}'

customer1 = Customer()
print(f'no name given, uses class name: {customer1}')
customer1.name = 'customer1'
print(f'instance name set: {customer1}')
print(f'class name still the same: {Customer.name}')
customer2 = Customer('customer2')
print(f'name set on instance: {customer2}')
Customer.name = 'Customer class name altered'
print(f'new class name: {Customer.name}')
print(f'customer1 now: {customer1}')
print(f'customer2 now: {customer2}')
Output:
no name given, uses class name: Class name: Customer class, instance name: Customer class instance name set: Class name: Customer class, instance name: customer1 class name still the same: Customer class name set on instance: Class name: Customer class, instance name: customer2 new class name: Customer class name altered customer1 now: Class name: Customer class name altered, instance name: customer1 customer2 now: Class name: Customer class name altered, instance name: customer2



RE: Understanding Class Variables - vindo - Jun-04-2019

(Jun-04-2019, 07:08 PM)Yoriz Wrote:
class Customer:
    name = 'Customer class'

    def __init__(self, name=None):
        if name:
            self.name = name

    def __repr__(self):
        return f'Class name: {Customer.name}, instance name: {self.name}'

customer1 = Customer()
print(f'no name given, uses class name: {customer1}')
customer1.name = 'customer1'
print(f'instance name set: {customer1}')
print(f'class name still the same: {Customer.name}')
customer2 = Customer('customer2')
print(f'name set on instance: {customer2}')
Customer.name = 'Customer class name altered'
print(f'new class name: {Customer.name}')
print(f'customer1 now: {customer1}')
print(f'customer2 now: {customer2}')
Output:
no name given, uses class name: Class name: Customer class, instance name: Customer class instance name set: Class name: Customer class, instance name: customer1 class name still the same: Customer class name set on instance: Class name: Customer class, instance name: customer2 new class name: Customer class name altered customer1 now: Class name: Customer class name altered, instance name: customer1 customer2 now: Class name: Customer class name altered, instance name: customer2


@Yoriz - I really appreciate you taking time to help me with my understanding.
I am new to this and slow in understanding. Please bear with me.

Let me break down my confusion into different questions.

Here goes the first,
How is that the values from customer_1 and customer_2 have also changed? I did not access them using <class_name>.<variable_name>, i used <instance_name>.<variable_name> ?

class Customer:
    name = "default"
   
customer_1 = Customer()
customer_2 = Customer()


print("")
print("name of class customer  ::", Customer.name)
print("name of customer 1 ::", customer_1.name)
print("name of customer 2 ::", customer_2.name)


print("")
print("Assigning new name by class ::")
Customer.name = "Class Name"
print("name of class customer  ::", Customer.name)
print("name of customer 1 ::", customer_1.name)
print("name of customer 2 ::", customer_2.name)
name of class customer  :: default
name of customer 1 :: default
name of customer 2 :: default

Assigning new name by class ::
name of class customer  :: Class Name
name of customer 1 :: Class Name
name of customer 2 :: Class Name



RE: Understanding Class Variables - Yoriz - Jun-04-2019

In this one the class Customer only has name attribute on the class, even when calling them as instance it is using the class name.

Objects are as follows

Class
  • name

customer_1
  • (has no attribute)

customer_2
  • (has no attribute)



RE: Understanding Class Variables - vindo - Jun-05-2019

(Jun-04-2019, 08:12 PM)Yoriz Wrote: In this one the class Customer only has name attribute on the class, even when calling them as instance it is using the class name.

Objects are as follows

Class
  • name

customer_1
  • (has no attribute)

customer_2
  • (has no attribute)

So, you mean to say, the moment i issue a statement "customer_1.name = "####"" an instance variable will be created for customer_1 and from that point forth the "name" field will be from the instance variable of customer_1.

Is that correct ?


RE: Understanding Class Variables - Yoriz - Jun-05-2019

Correct


RE: Understanding Class Variables - vindo - Jun-05-2019

(Jun-05-2019, 07:56 PM)Yoriz Wrote: Correct

Excellent!! Now its clear. Thank you for your patience.


RE: Understanding Class Variables - Yoriz - Jun-05-2019

Try this visualisation of python code site, you can step forward and backward through the code and it will show the objects.
http://pythontutor.com/visualize.html#code=class%20Customer%3A%0A%20%20%20%20name%20%3D%20%22default%22%0A%20%20%20%20%0Acustomer_1%20%3D%20Customer%28%29%0Acustomer_2%20%3D%20Customer%28%29%0A%0Acustomer_1.name%20%3D%20'this'&cumulative=false&curInstr=4&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false