class Point(object):
  pass

Point.ORIGIN = Point()
Answer from Ignacio Vazquez-Abrams on Stack Overflow
🌐
Python documentation
docs.python.org › 3 › tutorial › classes.html
9. Classes — Python 3.14.3 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.
Discussions

Can a python class have a class variable of this same class? - Stack Overflow
There is actually a similar question Class variables of same type as the class. More on stackoverflow.com
🌐 stackoverflow.com
Support different type for class variable and instance variable - Typing - Discussions on Python.org
After creating this feature request in pyright repo, i was told that this is not supported by python type spec and it’s best to discuss it here. The problem In django-modeltranslation, before we added types, we used class variable to populate instance variable with same name, but different type. More on discuss.python.org
🌐 discuss.python.org
0
May 25, 2024
Confused about class variables, also with inheritance
The class variables and instance variables remain separate if an instance variable of the same name is created. One doesn't override the other, but the class variable will no longer be readable via the object: In [1]: class c: ...: a = 1 ...: def __init__(self): ...: self.a = 2 ...: In [2]: obj = c() In [3]: c.a Out[3]: 1 In [4]: obj.a Out[4]: 2 As for inheritance, yes if you assign a value to a class variable on a child that has the same name as one of the parent's class variables, then a separate class variable of that name will be created for the child. Again, the two will remain separate, one readable from the parent and one readable from the child, but the parent's variable will no longer be visible via the child class. More on reddit.com
🌐 r/learnpython
10
17
February 24, 2024
When to use class variables vs instance variables
Codecademy is using a regular local variable here, not a class attribute. More on reddit.com
🌐 r/learnpython
25
2
February 9, 2023
🌐
DigitalOcean
digitalocean.com › community › tutorials › understanding-class-and-instance-variables-in-python-3
Understanding Class and Instance Variables in Python 3 | DigitalOcean
August 20, 2021 - Just like with any other variable, class variables can consist of any data type available to us in Python. In this program we have strings and an integer.
🌐
PYnative
pynative.com › home › python › python object-oriented programming (oop) › python class variables
Python Class Variables With Examples – PYnative
September 8, 2023 - In the above example, we created the class variable school_name and accessed it using the object and class name. Note: Like regular variables, class variables can store data of any type.
🌐
Career Karma
careerkarma.com › blog › python › python class variables vs. instance variables
Python Class Variables vs. Instance Variables | Career Karma
December 1, 2023 - This shows one of the main differences ... are the same across all instances. Python class variables are declared within a class and their values are the same across all instances of a class....
🌐
Python.org
discuss.python.org › typing
Support different type for class variable and instance variable - Typing - Discussions on Python.org
May 25, 2024 - After creating this feature request in pyright repo, i was told that this is not supported by python type spec and it’s best to discuss it here. The problem In django-modeltranslation, before we added types, we used class variable to populate instance variable with same name, but different type.
Find elsewhere
🌐
Python
typing.python.org › en › latest › spec › class-compat.html
Class type assignability — typing documentation
Since both variables happen to be initialized at the class level, it is useful to distinguish them by marking class variables as annotated with types wrapped in ClassVar[...]. In this way a type checker may flag accidental assignments to attributes with the same name on instances.
🌐
IONOS
ionos.com › digital guide › websites › web development › python class variables
How to create and use Python class variables
July 15, 2024 - In Python, we create class variables within a class. Unlike instance variables, which are specific to each instance of a class, class variables retain the same value for all instances.
🌐
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.
🌐
Reddit
reddit.com › r/learnpython › confused about class variables, also with inheritance
r/learnpython on Reddit: Confused about class variables, also with inheritance
February 24, 2024 -

I'm finding class variables super confusing. I thought they were just like static variables in C++ (which instances can't own), but it seems they have quite different behavior.

Basic Class variable behavior - is this correct?

class Foo:
  x: int
  • if you set Foo.x, it overrides the value of .x for all instances of Foo, but

  • if you set .x on an instance of Foo, it only changes .x on that instance.

edit: actually this can't be the full story, because sometimes changing Foo.x doesn't change the instance's .x??

Class variables + inheritance, what is going on?

class Parent:
  x: int

class Child(Parent):
  pass

Parent.x = 1      
print(Child.x)        # = 1. ok so child inherits parent class variable

Child.x = 2
print(Parent.x)       # = 1. ok, so child cannot set parent class variable

Parent.x = 3
print(Child.x)         # = 2. hol' up, now child doesn't inherit from parent anymore?

Also, if multiple classes inherit from Parent, if I set Child1.x does it affect the other children? How are instances affected too?

Class variables without declaration works too...?

What's the point of defining these variables in the class body if you don't need to?

class Foo:
   pass

Foo.x = 3

I feel like there's some kind of mental model for class variables I'm just not understanding. Is there any easy way to think about them? Also is there any other weird behavior I should know?

Top answer
1 of 5
5
The class variables and instance variables remain separate if an instance variable of the same name is created. One doesn't override the other, but the class variable will no longer be readable via the object: In [1]: class c: ...: a = 1 ...: def __init__(self): ...: self.a = 2 ...: In [2]: obj = c() In [3]: c.a Out[3]: 1 In [4]: obj.a Out[4]: 2 As for inheritance, yes if you assign a value to a class variable on a child that has the same name as one of the parent's class variables, then a separate class variable of that name will be created for the child. Again, the two will remain separate, one readable from the parent and one readable from the child, but the parent's variable will no longer be visible via the child class.
2 of 5
4
If you do an attribute lookup on an instance and the attribute isn't found on the instance itself, it will look on the class next. If you do an attribute lookup on a class and it isn't found on the class itself, it will look on the parent class next. If you do an attribute assignment, however, that always sets the attribute directly on the thing itself. That means, if you do an attribute assignment on an instance, even if its class already has an attribute of that name, you create a new instance attribute rather than reassigning the class attribute. Importantly, a lookup of that attribute on the instance would now no longer propagate up to the class. The same is true for classes and their parent classes. This becomes clearer if you take a look at the special __dict__ attribute of your classes and objects as you do the assignments, which holds all direct attributes of the object or class in dictionary form.
🌐
Reddit
reddit.com › r/learnpython › when to use class variables vs instance variables
r/learnpython on Reddit: When to use class variables vs instance variables
February 9, 2023 -

I thought I understood the use cases for class vs instance variables:

  • Class: when you want the variable to be the same across all objects

  • Instance: when you want the variable to be unique to each object

But I'm working through the Codecademy DSA with Python course, and doing an implementation of a hash map. The hashing function (.hash()) finds the byte-code version of the key string, and sums it for the hash. Why is Codecademy's solution of key_bytes using a class variable, vs I thought an instance variable is more appropriate? Because for each hash map I make, I will want a unique key_byte per object?

class HashMap:
  def __init__(self, array_size):
    self.array_size = array_size
    self.array = [None for item in range(array_size)]
  def hash(self, key):
    #codecademy forces this `key_bytes` as a class variable as solution
    key_bytes = key.encode()
    self.hash_code = sum(key_bytes)

    #why is `key_bytes` not an instance variable:
    self.key_bytes = key.encode()
    self.hash_code = sum(self.key_bytes)
Top answer
1 of 10
86

You can use a property like the other answers put it - so, if you want to constrain a single attribute, say "bar", and constrain it to an integer, you could write code like this:

class Foo(object):
    def _get_bar(self):
        return self.__bar
    def _set_bar(self, value):
        if not isinstance(value, int):
            raise TypeError("bar must be set to an integer")
        self.__bar = value
    bar = property(_get_bar, _set_bar)

And this works:

>>> f = Foo()
>>> f.bar = 3
>>> f.bar
3
>>> f.bar = "three"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in _set_bar
TypeError: bar must be set to an integer
>>> 

(There is also a new way of writing properties, using the "property" built-in as a decorator to the getter method - but I prefer the old way, like I put it above).

Of course, if you have lots of attributes on your classes, and want to protect all of them in this way, it starts to get verbose. Nothing to worry about - Python's introspection abilities allow one to create a class decorator that could automate this with a minimum of lines.

def getter_setter_gen(name, type_):
    def getter(self):
        return getattr(self, "__" + name)
    def setter(self, value):
        if not isinstance(value, type_):
            raise TypeError(f"{name} attribute must be set to an instance of {type_}")
        setattr(self, "__" + name, value)
    return property(getter, setter)

def auto_attr_check(cls):
    new_dct = {}
    for key, value in cls.__dict__.items():
        if isinstance(value, type):
            value = getter_setter_gen(key, value)
        new_dct[key] = value
    # Creates a new class, using the modified dictionary as the class dict:
    return type(cls)(cls.__name__, cls.__bases__, new_dct)

And you just use auto_attr_checkas a class decorator, and declar the attributes you want in the class body to be equal to the types the attributes need to constrain too:

...     
... @auto_attr_check
... class Foo(object):
...     bar = int
...     baz = str
...     bam = float
... 
>>> f = Foo()
>>> f.bar = 5; f.baz = "hello"; f.bam = 5.0
>>> f.bar = "hello"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in setter
TypeError: bar attribute must be set to an instance of <type 'int'>
>>> f.baz = 5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in setter
TypeError: baz attribute must be set to an instance of <type 'str'>
>>> f.bam = 3 + 2j
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in setter
TypeError: bam attribute must be set to an instance of <type 'float'>
>>> 

    
2 of 10
47

Since Python 3.5, you can use type-hints to indicate that a class attribute should be of a particular type. Then, you could include something like MyPy as part of your continuous integration process to check that all the type contracts are respected.

For example, for the following Python script:

class Foo:
    x: int
    y: int

foo = Foo()
foo.x = "hello"

MyPy would give the following error:

6: error: Incompatible types in assignment (expression has type "str", variable has type "int")

If you want types to be enforced at runtime, you could use the enforce package. From the README:

>>> import enforce
>>>
>>> @enforce.runtime_validation
... def foo(text: str) -> None:
...     print(text)
>>>
>>> foo('Hello World')
Hello World
>>>
>>> foo(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/william/.local/lib/python3.5/site-packages/enforce/decorators.py", line 106, in universal
    _args, _kwargs = enforcer.validate_inputs(parameters)
  File "/home/william/.local/lib/python3.5/site-packages/enforce/enforcers.py", line 69, in validate_inputs
    raise RuntimeTypeError(exception_text)
enforce.exceptions.RuntimeTypeError: 
  The following runtime type errors were encountered:
       Argument 'text' was not of type <class 'str'>. Actual type was <class 'int'>.
🌐
Toptal
toptal.com › python › python-class-attributes-an-overly-thorough-guide
Python Class Attributes: Examples of Variables | Toptal®
January 16, 2026 - What if your class attribute has a mutable type? You can manipulate the class attribute by accessing it through a particular instance and, in turn, end up manipulating the referenced object that all instances are accessing (as pointed out by Timothy Wiseman). Let’s go back to the Service I defined earlier and see how my use of a class variable could have led to problems down the road: {:lang='python'} class Service(object): data = [] def __init__(self, other_data): self.other_data = other_data ...
🌐
Reddit
reddit.com › r/learnpython › how can i make a class take an object of the same type as a constructor argument? currently get unresolved reference...
r/learnpython on Reddit: How can I make a class take an object of the same type as a constructor argument? Currently get unresolved reference...
March 16, 2023 -

I am more familiar with C++ so maybe this isn't the python way to do things, but I want to overload the __init__ function of my class "Component" so that I can construct a new object of that type by passing an object of that type that already exists. Reason for doing it this way is that the class has a parent/child structure and so copying the parent requires careful handling of the family tree, I aim to solve this eventually with recursion, using this overloaded constructor as an aid to avoid bloating my copying function with loads of setter lines setting new objects to their appropriate values.

Currently my class that drives from Component (Group) looks like this:

from Components.component import Component, ComponentType


class Group(Component):
    def __init__(self,
                 component_name: str,
                 ):

        if component_name is None:
            component_name = "New Group"

        super().__init__(component_name=component_name, component_type=ComponentType.Group)

        self.children: list[Component] = []

    def __init__(self, clone: Group): <- This line claims unresolved reference to group, but it is a member of that class!
        pass

    def add_child(self, new_child: Component):
        if new_child not in self.children:
            self.children.append(new_child)
        else:
            print(f"Oh no! {new_child.component_name} is already owned by {self.component_name}!")

    def remove_child(self, old_child: Component):
        if old_child in self.children:
            self.children.remove(old_child)

Feel free to tell me I'm handling this totally wrong! It's just the way that came to mind when looking to solve my current problem haha.

Top answer
1 of 2
2
Firstly, there is no such thing as method overloading in Python[*]. Defining two methods with the same name just means that the second completely replaces the first. This can't work as written. If you really want to do this, one way would be to define a classmethod: class Group(Component): ... @classmethod def from_group(cls, clone: "Group"): return cls(...) although if the idea is just to clone a group you might as well make it an instance method that returns a clone of the current instance. Note, my code above shows the solution to your actual question: you need to put the class name in quotes. An alternative is to import a magic future declaration that enables postponed evaluation of annotations: from __future__ import annotations Then your original declaration will work (although not the code itself, as I note). This was actually supposed to be the default from Python 3.10, but the change has been delayed. [*] there is functools.singledispatchmethod , but it's not used much and it would be pretty strange to use it on the __init__.)
2 of 2
1
I want to overload the init function of my class "Component" so that I can construct a new object of that type by passing an object of that type that already exists. Python doesn't have method overloading (although there is a tool for type-based dispatch in the std lib somewhere) so it would be better to use a factory classmethod for this. But let's talk about why your type declaration can't work: def __init__(self, clone: Group): <- This line claims unresolved reference to group, but it is a member of that class! Ah, but remember, this is Python; there's no compile step. Your class is created in runtime! That means that at the time you're referencing Group, it doesn't exist yet. You're in the process of defining it, still, so there's no value that has that name yet (that's the last thing that happens as you define a class.) You need Self, from typing, to address the circularity, here: from typing import Self # ... def __init__(self, clone: Self): # etc, except you can't have two __init__ methods
🌐
Python Tutorial
pythontutorial.net › home › python oop › python class variables
Python Class Variables Explained
March 31, 2025 - When you define a class using the class keyword, Python creates an object with the name the same as the class’s name. For example: class HtmlDocument: passCode language: Python (python) This example defines the HtmlDocument class and the HtmlDocument object. The HtmlDocument object has the __name__ property: class HtmlDocument: pass print(HtmlDocument.__name__)Code language: Python (python) ... Class variables are bound to the class. They’re shared by all instances of that class.
🌐
Reddit
reddit.com › r/learnpython › can someone explain how object/instance variables vs class/static variables work in python?
r/learnpython on Reddit: Can someone explain how object/instance variables vs class/static variables work in Python?
July 6, 2023 -

So I come from a Java background where defining, declaring and accessing static and instance level variables are pretty much a straightforward process. I want to be able to understand OOP concepts of Python properly so I have been doing some practice.

I have a class:

class A:

def init(self): pass

def someFunc(self): self.var1 += 1

I create an object of this class and call the someFunc() method:

a = A() 
a.someFunc()

It gives me an error. Ok, fair enough since I haven't declared a self.var1 variable yet.

Consider another example.

class A:

var1 = 10

def init(self): pass

def someFunc(self): self.var1 += 1

Now when I do this:

a = A()
a.someFunc()

Output: 11

I know that variables defined just below the class definition are class/static variables. And to access them you have to do A.var1

But why does it not give me an error now? I haven't created a object/instance level self.var1 variable yet, just a class level variable var1.

And when I call A.var1 the output is 10. Why is the output not the same as a.var1?

Does python automatically use the class level variable with the same name since there is no instance level variable defined with the same name? And does that in turn become a different variable from the class level variable?

Can someone please elaborate?

Top answer
1 of 11
9
In the first example, you get an error because the attribute, var1, hasn't been defined before you use it in an expression. So, you would need to do this. class A: def __init__(self): pass def some_func(self): self.var1 += 1 a = A() a.var1 = 0 # create attribute a.some_func() print(a.var1) In your second example, as you've defined a class variable, that is used to define the instance variable the first time you use a local assignment expression in the instance method. Thus, in the below, you will find that a has an instance variable but b doesn't, class A: var1 = 0 def __init__(self): pass def some_func(self): self.var1 += 1 a = A() b = A() a.some_func() print(a.var1, b.var1) print(vars(a), vars(b)) # outputs all the attributes of the instances PS. If I modify the class variable, A.var1 += 10 then you would find b.var1 was also changed (because it is pointing to the same object).
2 of 11
5
In python classes a reference to self.varname first looks for an instance attribute varname. If found, it is used. But if not found the class variable varname is used, if it exists. When assigning to self.varname an instance attribute is always created or updated, leaving any class variable of the same name unchanged. You can see that in this code, based on your second example: class A: var1 = 10 # no need to use "pass" in __init__() def someFunc(self): self.var1 += 1 a = A() a.someFunc() print(f"{a.var1=}, {A.var1=}") Run that code and you will see the instance variable is 11 and the class variable remains unchanged at 10. It's good practice to always refer to class variables by A.var1 so you don't fall into the trap of thinking assigning to self.var1 changes the class variable of name var1.
🌐
iBiblio
ibiblio.org › g2swap › byteofpython › read › class-and-object-vars.html
Class and Object Variables
In this case, each object has its own copy of the field i.e. they are not shared and are not related in any way to the field by the samen name in a different instance of the same class. An example will make this easy to understand. Example 11.4. Using Class and Object Variables · #!/usr/bin/python # Filename: objvar.py class Person: '''Represents a person.''' population = 0 def __init__(self, name): '''Initializes the person's data.''' self.name = name print '(Initializing %s)' % self.name # When this person is created, he/she # adds to the population Person.population += 1 def __del__(self): '''I am dying.''' print '%s says bye.'
🌐
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. Always modify shared data through the class. Let’s say you have multiple objects that all rely on the same configuration value, such as a timeout.