Python Forum
Understanding Class Variables
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Understanding Class Variables
#1
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
Reply
#2
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
Reply
#3
(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?
Reply
#4
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
Reply
#5
(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
Reply
#6
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)
Reply
#7
(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 ?
Reply
#8
Correct
Reply
#9
(Jun-05-2019, 07:56 PM)Yoriz Wrote: Correct

Excellent!! Now its clear. Thank you for your patience.
Reply
#10
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#co...nces=false
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Unchangeable variables in a class? Calab 12 1,539 Sep-15-2023, 07:15 PM
Last Post: deanhystad
  Problems with understanding class index. Brainbit 3 936 Sep-20-2022, 07:52 PM
Last Post: Brainbit
  Class variables and Multiprocessing(or concurrent.futures.ProcessPoolExecutor) Tomli 5 3,889 Nov-12-2021, 09:55 PM
Last Post: snippsat
  How to pass variables from one class to another hobbyist 18 10,701 Oct-01-2021, 05:54 PM
Last Post: deanhystad
  Acess variables from class samuelbachorik 3 1,899 Aug-20-2021, 02:55 PM
Last Post: deanhystad
  Class variables menator01 2 2,007 Jun-04-2020, 04:23 PM
Last Post: Yoriz
  Question about naming variables in class methods sShadowSerpent 1 2,007 Mar-25-2020, 04:51 PM
Last Post: ndc85430
  What is the strategy for working with class variables? AlekseyPython 3 3,003 Feb-24-2019, 05:34 AM
Last Post: AlekseyPython
  Base class variables are not accessible Prabakaran141 3 2,814 Oct-31-2018, 07:13 AM
Last Post: buran
  Class Modules, and Passing Variables: Seeking Advice Robo_Pi 21 10,270 Mar-02-2018, 05:22 PM
Last Post: snippsat

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020