This is because of the way Python resolves names with the .. When you write self.list the Python runtime tries to resolve the list name first by looking for it in the instance object, and if it is not found there, then in the class instance.

Let's look into it step by step

self.list.append(1)
  1. Is there a list name into the object self?
    • Yes: Use it! Finish.
    • No: Go to 2.
  2. Is there a list name into the class instance of object self?
    • Yes: Use it! Finish
    • No: Error!

But when you bind a name things are different:

self.list = []
  1. Is there a list name into the object self?
    • Yes: Overwrite it!
    • No: Bind it!

So, that is always an instance variable.

Your first example creates a list into the class instance, as this is the active scope at the time (no self anywhere). But your second example creates a list explicitly in the scope of self.

More interesting would be the example:

class testClass():
    list = ['foo']
    def __init__(self):
        self.list = []
        self.list.append('thing')

x = testClass()
print x.list
print testClass.list
del x.list
print x.list

That will print:

['thing']
['foo']
['foo']

The moment you delete the instance name the class name is visible through the self reference.

Answer from rodrigo on Stack Overflow
🌐
Python documentation
docs.python.org › 3 › tutorial › classes.html
9. Classes — Python 3.14.7 documentation
To rebind variables found outside of the innermost scope, the nonlocal statement can be used; if not declared nonlocal, those variables are read-only (an attempt to write to such a variable will simply create a new local variable in the innermost scope, leaving the identically named outer variable unchanged). Usually, the local scope references the local names of the (textually) current function. Outside functions, the local scope references the same namespace as the global scope: the module’s namespace. Class definitions place yet another namespace in the local scope.
Top answer
1 of 4
67

This is because of the way Python resolves names with the .. When you write self.list the Python runtime tries to resolve the list name first by looking for it in the instance object, and if it is not found there, then in the class instance.

Let's look into it step by step

self.list.append(1)
  1. Is there a list name into the object self?
    • Yes: Use it! Finish.
    • No: Go to 2.
  2. Is there a list name into the class instance of object self?
    • Yes: Use it! Finish
    • No: Error!

But when you bind a name things are different:

self.list = []
  1. Is there a list name into the object self?
    • Yes: Overwrite it!
    • No: Bind it!

So, that is always an instance variable.

Your first example creates a list into the class instance, as this is the active scope at the time (no self anywhere). But your second example creates a list explicitly in the scope of self.

More interesting would be the example:

class testClass():
    list = ['foo']
    def __init__(self):
        self.list = []
        self.list.append('thing')

x = testClass()
print x.list
print testClass.list
del x.list
print x.list

That will print:

['thing']
['foo']
['foo']

The moment you delete the instance name the class name is visible through the self reference.

2 of 4
10

Python has interesting rules about looking up names. If you really want to bend your mind, try this code:

class testClass():
    l = []
    def __init__(self):
        self.l = ['fred']

This will give each instance a variable called l that masks the class variable l. You will still be able to get at the class variable if you do self.__class__.l.

The way I think of it is this... Whenever you do instance.variable (even for method names, they're just variables who's values happen to be functions) it looks it up in the instance's dictionary. And if it can't find it there, it tries to look it up in the instance's class' dictionary. This is only if the variable is being 'read'. If it's being assigned to, it always creates a new entry in the instance dictionary.

People also ask

How do I correctly declare and initialize class variables in Python?
To declare a class variable, define it directly within the class block but outside of any methods. For example:nnclass MyClass:n shared_counter = 0 # class variablennYou can initialize class variables with any value, including numbers, strings, or data structures. Remember that class variables are shared among all instances, so be cautious when modifying mutable objects like lists or dictionaries to avoid unintended side effects.
🌐
ituonline.com
ituonline.com › blogs › python-class-variables
Python Class Variables: Declaration, Usage, and Practical Examples ...
What are class variables in Python and how do they differ from instance variables?
Class variables in Python are variables that are shared across all instances of a class. They are defined within the class but outside of any instance methods, making them accessible to all objects created from that class.nIn contrast, instance variables are unique to each object. They are usually defined within the __init__ method using self, such as self.variable_name. Changes to instance variables affect only that particular object, whereas class variables reflect shared data across all instances.
🌐
ituonline.com
ituonline.com › blogs › python-class-variables
Python Class Variables: Declaration, Usage, and Practical Examples ...
What are common pitfalls when using class variables in Python?
One common mistake is modifying mutable class variables, such as lists or dictionaries, which can lead to unexpected behavior across all instances. For example, appending to a shared list affects all objects referencing that list.nAnother pitfall is accidentally creating instance variables with the same name as class variables by assignment within an instance method, which can shadow the class variable. This can cause confusion and bugs, especially in larger codebases.nTo avoid these issues, prefer to modify mutable class variables through the class itself and be mindful of variable shadowing.
🌐
ituonline.com
ituonline.com › blogs › python-class-variables
Python Class Variables: Declaration, Usage, and Practical Examples ...
🌐
GeeksforGeeks
geeksforgeeks.org › python › g-fact-34-class-or-static-variables-in-python
Class (Static) and Instance Variables in Python - GeeksforGeeks
Class variables are shared by all objects of a class, whereas instance variables are unique to each object. Unlike languages such as Java or C++, Python does not require a static keyword.
Published: March 6, 2026
🌐
PYnative
pynative.com › home › python › python object-oriented programming (oop) › python class variables
Python Class Variables With Examples – PYnative
September 8, 2023 - Class Variables: A class variable is a variable that is declared inside of a class but outside of any instance method or init() method. Class variables are shared by all instances of a class. Read More: Instance variables in Python with Examples
🌐
IONOS
ionos.com › digital guide › websites › web development › python class variables
How to create and use Python class variables - IONOS
July 15, 2024 - Python class variables are variables that keep the same value for every instance of a class. We’ll go over their syntax and different ways you can use them.
🌐
Python Tutorial
pythontutorial.net › home › python oop › python class variables
Python Class Variables Explained
March 31, 2025 - If you access a class variable that doesn’t exist, you’ll get an AttributeError exception. For example: class HtmlDocument: extension = 'html' version = '5' print(HtmlDocument.media_type)Code language: Python (python)
Find elsewhere
🌐
ITU Online
ituonline.com › blogs › python-class-variables
Python Class Variables: Declaration, Usage, and Practical Examples – ITU Online IT Training
August 3, 2023 - The key rule is simple: if the value can differ from object to object, it probably belongs in an instance variable. If it describes the class itself, a class variable is a reasonable fit. For a deeper look at Python attribute behavior, the glossary definition for Inheritance helps explain why subclass lookups can also see class variables from parent classes.
🌐
Career Karma
careerkarma.com › blog › python › python class variables vs. instance variables
Python Class Variables vs. Instance Variables | Career Karma
December 1, 2023 - Python class variables are defined within a class constructor and have the same value across all instances of a class. On Career Karma, learn how to use Python class and instance variables.
🌐
CBT Nuggets
cbtnuggets.com › blog › technology › programming › python-class-variables-explained
Python Class Variables: Explained
Here is a good way to sum up the relationship: a class variables is shared by all objects that are created. An instance of the class variable is always created on each newly minted object; it overrides the class instance. Lastly, an instance variable is only accessible to the object it was defined in. Warning: The following code will only work in Python 3.x
🌐
YouTube
youtube.com › watch
Python Class Variables - YouTube
Class Variables in Python. Class Variables are variables shared by all instances of a class. This differs from an instance variable, also known as an attribu...
Published: March 10, 2025
🌐
Syntaxdb
syntaxdb.com › ref › python › class-variables
Class and Instance Variables in Python - SyntaxDB - Python Syntax Reference
Used declare variables within a class. There are two main types: class variables, which have the same value across all class instances (i.e. static variables), and instance variables, which have different values for each object instance.
🌐
DigitalOcean
digitalocean.com › community › tutorials › understanding-class-and-instance-variables-in-python-3
Understanding Class and Instance Variables in Python 3 | DigitalOcean
Learn the difference between class and instance variables in Python 3 with clear examples, a comparison table, and FAQs. Write better OOP code today.
🌐
W3Resource
w3resource.com › python-interview › what-are-python-class-variables.php
What are Python class variables?
Python class variables are variables that are shared among all instances (objects) of a class.
🌐
Dive into Python
diveintopython.org › home › learn python programming › classes in python › class variables, attributes, and properties
Class Variables and Properties in Python: Public, Private and Protected
May 3, 2024 - Properties: A property is a way to define a method as an attribute. Properties are created using the @property decorator. In Python, class variables are a powerful way to share data among all instances of a class.
🌐
Python.org
discuss.python.org › python help
Class variables - Python Help - Discussions on Python.org
August 14, 2022 - Hi, I am confused about class variable and instance variable in below example: class Classy: varia = 2 def method(self): print(self.varia, self.var) obj = Classy() obj.var = 3 obj.method() Don’t we access class variables like Example.varia and access object variables as self.varia?
Top answer
1 of 2
772

Neither way is necessarily correct or incorrect, they are just two different kinds of class elements:

  • Elements outside the __init__ method are static elements; they belong to the class.
  • Elements inside the __init__ method are elements of the object (self); they don't belong to the class.

You'll see it more clearly with some code:

class MyClass:
    static_elem = 123

    def __init__(self):
        self.object_elem = 456

c1 = MyClass()
c2 = MyClass()

# Initial values of both elements
>>> print c1.static_elem, c1.object_elem 
123 456
>>> print c2.static_elem, c2.object_elem
123 456

# Nothing new so far ...

# Let's try changing the static element
MyClass.static_elem = 999

>>> print c1.static_elem, c1.object_elem
999 456
>>> print c2.static_elem, c2.object_elem
999 456

# Now, let's try changing the object element
c1.object_elem = 888

>>> print c1.static_elem, c1.object_elem
999 888
>>> print c2.static_elem, c2.object_elem
999 456

As you can see, when we changed the class element, it changed for both objects. But, when we changed the object element, the other object remained unchanged.

2 of 2
25

I think this sample explains the difference between the styles:

james@bodacious-wired:~$cat test.py 
#!/usr/bin/env python

class MyClass:
    element1 = "Hello"

    def __init__(self):
        self.element2 = "World"

obj = MyClass()

print dir(MyClass)
print "--"
print dir(obj)
print "--"
print obj.element1 
print obj.element2
print MyClass.element1 + " " + MyClass.element2
james@bodacious-wired:~$./test.py 
['__doc__', '__init__', '__module__', 'element1']
--
['__doc__', '__init__', '__module__', 'element1', 'element2']
--
Hello
World
Traceback (most recent call last):
  File "./test.py", line 17, in <module>
    print MyClass.element2
AttributeError: class MyClass has no attribute 'element2'

element1 is bound to the class, element2 is bound to an instance of the class.

🌐
Medium
medium.com › @pouyahallaj › class-vs-instance-variables-in-python-5573e71c99b5
Python Class Variables vs. Instance | Pouya Hallaj | Medium
September 16, 2023 - They differ from instance variables in that they are shared among all instances, providing a convenient way to store constants, track instance counts, and manage shared state. Understanding when and how to use class variables can greatly enhance your Python programming skills and improve code organization.
🌐
Digis
digiscorp.com › understanding-python-class-variables-a-beginners-guide
Understanding Python Class Variables: A Beginner's Guide
July 22, 2025 - If you assign a new value to a class variable using an instance, Python will create an instance variable instead — shadowing the class variable.
🌐
Ttu
ttu.github.io › python-class-instance-variables
Python Class and Instance Variables
July 14, 2022 - In particular, the value-less notation a: int allows one to annotate instance variables that should be initialized in init or new. The proposed syntax is as follows: ... from typing import ClassVar class Starship: captain: str = "Picard" # instance variable with default damage: int # instance variable without default stats: ClassVar[dict[str, int]] = {} # class variable def __init__(self, damage: int, captain: str | None = None): self.damage = damage if captain: self.captain = captain # Else keep the default def hit(self) -> None: Starship.stats['hits'] = Starship.stats.get('hits', 0) + 1 # No