If you have only the one class and you only read the variable, you won't see a lot of difference.

If you take into account the possibility of subclasses that override class_var, then self.class_var will look in the current class first while Foo.class_var will continue to refer concretely to that particular value. The best practice depends on your intent but since using classes in a language that makes them optional implies at least some interest in polymorphism, self is probably more generally useful.

Also, if you want to set the value, self.whatever = will set an instance variable and Foo.whatever = will set the class variable which could then affect any other instance as well.

Answer from Jason S on Stack Overflow
🌐
PYnative
pynative.com › home › python › python object-oriented programming (oop) › python class variables
Python Class Variables With Examples – PYnative
September 8, 2023 - In Python, we can access the class variable in the following places · Access inside the constructor by using either self parameter or class name. Access class variable inside instance method by using either self of class name · Access from outside of class by using either object reference or class name.
🌐
Reddit
reddit.com › r/learnpython › how to reference class variables inside class method
r/learnpython on Reddit: How to reference class variables inside class method
November 5, 2022 -
class Test:
    config: Dict[str, str]
    parameters: Dict[str, str]

    def default(cls)
        return cls(
                parameters=get_params(),
                config=get_config(file="ATTRIBUTE FROM PARAMETERS"
        )
# I tried it like this:

class Test:
    config: Dict[str, str]
    parameters: Dict[str, str]

    def default(cls)
        return cls(
                parameters=get_params(),
                config=get_config(file=cls.parameters.config_file)
        )
# AttributeError: type object 'Test' has no attribute 'parameters'
Discussions

How should I refer to class variables in Python? - Stack Overflow
In Python I can refer to a class level variable with either ClassName.class_var or self.class_var from within a class. Now as long as I do not override the class level variables name within an obje... More on stackoverflow.com
🌐 stackoverflow.com
python - How do I pass a variable by reference? - Stack Overflow
Also, have a look at pythontutor.com ... "Fluent Python" 2025-08-25T23:47:47.98Z+00:00 ... Save this answer. ... Show activity on this post. You can merely use an empty class as an instance to store reference objects because internally object attributes are stored in an instance dictionary. See the example. Copyclass RefsObj(object): "A class which helps to create references to variables." pass ... More on stackoverflow.com
🌐 stackoverflow.com
Python - how can I reference a class variable or method from within the __init__ method? - Stack Overflow
You need to use the full classname to set class variables. cls in double_x and tripple_x will refer to subclasses (ObjectOne and ObjectTwo, respectively), and setting attributes on those subclasses will store new variables, not alter the class variable BaseObject.x. More on stackoverflow.com
🌐 stackoverflow.com
December 31, 2012
Class variables
Don’t we access class variables like Example.varia and access object variables as self.varia · Yes, to be clear, you would usually refer to a class attribute via the class. But in an instance method (a normal" method), you’ve got self, not the class. You could write: More on discuss.python.org
🌐 discuss.python.org
5
0
August 14, 2022
🌐
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.
Top answer
1 of 16
3595

Arguments are passed by assignment. The rationale behind this is twofold:

  1. the parameter passed in is actually a reference to an object (but the reference is passed by value)
  2. some data types are mutable, but others aren't

So:

  • If you pass a mutable object into a method, the method gets a reference to that same object and you can mutate it to your heart's delight, but if you rebind the reference in the method, the outer scope will know nothing about it, and after you're done, the outer reference will still point at the original object.

  • If you pass an immutable object to a method, you still can't rebind the outer reference, and you can't even mutate the object.

To make it even more clear, let's have some examples.

List - a mutable type

Let's try to modify the list that was passed to a method:

def try_to_change_list_contents(the_list):
    print('got', the_list)
    the_list.append('four')
    print('changed to', the_list)

outer_list = ['one', 'two', 'three']

print('before, outer_list =', outer_list)
try_to_change_list_contents(outer_list)
print('after, outer_list =', outer_list)

Output:

before, outer_list = ['one', 'two', 'three']
got ['one', 'two', 'three']
changed to ['one', 'two', 'three', 'four']
after, outer_list = ['one', 'two', 'three', 'four']

Since the parameter passed in is a reference to outer_list, not a copy of it, we can use the mutating list methods to change it and have the changes reflected in the outer scope.

Now let's see what happens when we try to change the reference that was passed in as a parameter:

def try_to_change_list_reference(the_list):
    print('got', the_list)
    the_list = ['and', 'we', 'can', 'not', 'lie']
    print('set to', the_list)

outer_list = ['we', 'like', 'proper', 'English']

print('before, outer_list =', outer_list)
try_to_change_list_reference(outer_list)
print('after, outer_list =', outer_list)

Output:

before, outer_list = ['we', 'like', 'proper', 'English']
got ['we', 'like', 'proper', 'English']
set to ['and', 'we', 'can', 'not', 'lie']
after, outer_list = ['we', 'like', 'proper', 'English']

Since the the_list parameter was passed by value, assigning a new list to it had no effect that the code outside the method could see. The the_list was a copy of the outer_list reference, and we had the_list point to a new list, but there was no way to change where outer_list pointed.

String - an immutable type

It's immutable, so there's nothing we can do to change the contents of the string

Now, let's try to change the reference

def try_to_change_string_reference(the_string):
    print('got', the_string)
    the_string = 'In a kingdom by the sea'
    print('set to', the_string)

outer_string = 'It was many and many a year ago'

print('before, outer_string =', outer_string)
try_to_change_string_reference(outer_string)
print('after, outer_string =', outer_string)

Output:

before, outer_string = It was many and many a year ago
got It was many and many a year ago
set to In a kingdom by the sea
after, outer_string = It was many and many a year ago

Again, since the the_string parameter was passed by value, assigning a new string to it had no effect that the code outside the method could see. The the_string was a copy of the outer_string reference, and we had the_string point to a new string, but there was no way to change where outer_string pointed.

I hope this clears things up a little.

EDIT: It's been noted that this doesn't answer the question that @David originally asked, "Is there something I can do to pass the variable by actual reference?". Let's work on that.

How do we get around this?

As @Andrea's answer shows, you could return the new value. This doesn't change the way things are passed in, but does let you get the information you want back out:

def return_a_whole_new_string(the_string):
    new_string = something_to_do_with_the_old_string(the_string)
    return new_string

# then you could call it like
my_string = return_a_whole_new_string(my_string)

If you really wanted to avoid using a return value, you could create a class to hold your value and pass it into the function or use an existing class, like a list:

def use_a_wrapper_to_simulate_pass_by_reference(stuff_to_change):
    new_string = something_to_do_with_the_old_string(stuff_to_change[0])
    stuff_to_change[0] = new_string

# then you could call it like
wrapper = [my_string]
use_a_wrapper_to_simulate_pass_by_reference(wrapper)

do_something_with(wrapper[0])

Although this seems a little cumbersome.

2 of 16
909

The problem comes from a misunderstanding of what variables are in Python. If you're used to most traditional languages, you have a mental model of what happens in the following sequence:

a = 1
a = 2

You believe that a is a memory location that stores the value 1, then is updated to store the value 2. That's not how things work in Python. Rather, a starts as a reference to an object with the value 1, then gets reassigned as a reference to an object with the value 2. Those two objects may continue to coexist even though a doesn't refer to the first one anymore; in fact they may be shared by any number of other references within the program.

When you call a function with a parameter, a new reference is created that refers to the object passed in. This is separate from the reference that was used in the function call, so there's no way to update that reference and make it refer to a new object. In your example:

def __init__(self):
    self.variable = 'Original'
    self.Change(self.variable)

def Change(self, var):
    var = 'Changed'

self.variable is a reference to the string object 'Original'. When you call Change you create a second reference var to the object. Inside the function you reassign the reference var to a different string object 'Changed', but the reference self.variable is separate and does not change.

The only way around this is to pass a mutable object. Because both references refer to the same object, any changes to the object are reflected in both places.

def __init__(self):         
    self.variable = ['Original']
    self.Change(self.variable)

def Change(self, var):
    var[0] = 'Changed'
Top answer
1 of 2
7

You need to use the full classname to set class variables. cls in double_x and tripple_x will refer to subclasses (ObjectOne and ObjectTwo, respectively), and setting attributes on those subclasses will store new variables, not alter the class variable BaseObject.x. You can only alter base class variables by directly accessing them.

Using your code, we get:

>>> obj_1 = ObjectOne()
cls.initialized = False
>>> obj_1.double_x()
2
>>> obj_2 = ObjectTwo()
cls.initialized = False
>>> obj_2.triple_x()
3
>>> BaseObject.x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'BaseObject' has no attribute 'x'
>>> BaseObject.initialized, ObjectOne.initialized, ObjectOne.x, ObjectTwo.initialized, ObjectTwo.x
(False, True, 2, True, 3)

What happened is that in _initialize(), cls was set to ObjectOne or ObjectTwo, depending on what instance you created, and each subclass got their own copies of the variables initialized and x.

Using BaseObject._initialize() (to ensure that BaseObject is initialized, and not the subclasses) gives:

>>> obj_1 = ObjectOne()
cls.initialized = False
>>> obj_1.double_x()
2
>>> obj_2 = ObjectTwo()
cls.initialized = True
>>> obj_2.triple_x()
3
>>> BaseObject.x, ObjectOne.x, ObjectTwo.x
(1, 2, 3)
>>> BaseObject.initialized
True
>>> 'x' in ObjectOne.__dict__
True
>>> 'initialized' in ObjectOne.__dict__
False
>>> 'initialized' in ObjectTwo.__dict__
False

So now _initialize() used BaseObject as the target to set initialized and the initial value for x, but double_x and triple_x still used their own subclasses to set the new value of x and are not sharing that value through BaseObject.

The only option you have to set class variables on a specific base class is to refer to it directly in all class methods:

class BaseObject(object):
    initialized = False
    def __init__(self):
        BaseObject._initialize()

    @classmethod
    def _initialize(cls):
        print "cls.initialized = "+str(cls.initialized)
        if not cls.initialized:
            cls.x = 1
            cls.initialized = True
class ObjectOne(BaseObject):
    @classmethod
    def double_x(cls):
        BaseObject.x = BaseObject.x * 2
        print cls.x

class ObjectTwo(BaseObject):
    @classmethod
    def triple_x(cls):
        BaseObject.x = BaseObject.x * 3
        print cls.x

which would give:

>>> obj_1 = ObjectOne()
cls.initialized = False
>>> obj_1.double_x()
2
>>> obj_2 = ObjectTwo()
cls.initialized = True
>>> obj_2.triple_x()
6

Note that I called BaseObject._initialize() to make sure that cls is BasObject and not a subclass. Then, when setting x the double_x and triple_x methods still refer directly to BaseObject to ensure that the variable is set directly on the base class. When reading the value of x the above example still uses cls, which uses the class MRO to find x on the base class when not set locally.

2 of 2
1

You have two issues.first of all in order to call the class method inside the class,you must use the COMPLETE name of the class:BaseObject._initialize() second of all, every time you make a new instance of ObjectOne or ObjectTwo,you are overwriting the BaseObject.x within its environment,so others use the initialized x attribute instead of the changed one.to fix this you must change two lines:

cls.x = cls.x * 2 To BaseObject.x = cls.x * 2

and

cls.x = cls.x * 3 To BaseObject.x = cls.x * 3

Find elsewhere
🌐
IONOS
ionos.com › digital guide › websites › web development › python class variables
How to create and use Python class variables - IONOS
July 15, 2024 - In Python, you can access class variables in various places: In the con­struc­tor: You can call the class variable in the con­struc­tor using either the self keyword or the class name. In instance methods: You can call the class variable in instance methods using either the self keyword or the class name. Outside the class: You can access the class variable outside the class via the object reference or using the class name.
🌐
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 …
🌐
GeeksforGeeks
geeksforgeeks.org › python-using-variable-outside-and-inside-the-class-and-method
Python | Using variable outside and inside the class and method - GeeksforGeeks
May 18, 2020 - In simple terms, variables are names attached to particular objects in Python. To create a variable, you just need to assign a value and then start using it.
🌐
GeeksforGeeks
geeksforgeeks.org › different-ways-to-access-instance-variable-in-python
Different ways to access Instance Variable in Python - GeeksforGeeks
March 27, 2024 - Time complexity: O(1) for both creating the class and calling the display() method and accessing the name variable outside the class. Auxiliary space: O(1) as there are no additional data structures used and the memory space is constant. ... # Python code for accessing attributes of class class emp: name='Harsh' salary='25000' def show(self): print(self.name) print(self.salary) # Driver Code e1 = emp() # Use getattr instead of e1.name print(getattr(e1,'name')) # returns true if object has attribute print(hasattr(e1,'name')) # sets an attribute setattr(e1,'height',152) # returns the value of attribute name height print(getattr(e1,'height')) # delete the attribute delattr(emp,'salary')
🌐
Python documentation
docs.python.org › 3 › tutorial › classes.html
9. Classes — Python 3.14.8 documentation
1 week ago - It is not necessary that the function definition is textually enclosed in the class definition: assigning a function object to a local variable in the class is also ok. For example: # Function defined outside the class def f1(self, x, y): return min(x, x+y) class C: f = f1 def g(self): return 'hello world' h = g · Now f, g and h are all attributes of class C that refer to function objects, and consequently they are all methods of instances of C — h being exactly equivalent to g.
🌐
Toptal
toptal.com › python › python-class-attributes-an-overly-thorough-guide
Python Class Attributes: Examples of Variables | Toptal®
January 16, 2026 - 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 ...
🌐
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 - class Team: team_name = "Python ... the value of a class variable is straightforward. You use the class name to reference the variable and assign a new value to it....
🌐
Real Python
realpython.com › python-pass-by-reference
Pass by Reference in Python: Background and Best Practices – Real Python
March 18, 2026 - Free Bonus: 5 Thoughts On Python Mastery, a free course for Python developers that shows you the roadmap and the mindset you’ll need to take your Python skills to the next level. Before you dive into the technical details of passing by reference, it’s helpful to take a closer look at the term itself by breaking it down into components: Pass means to provide an argument to a function. By reference means that the argument you’re passing to the function is a reference to a variable that already exists in memory rather than an independent copy of that variable.
Top answer
1 of 4
8

Class body in python is an executable context, not like Java that only contains declaration. What this ultimately means is that sequence of execution is important within a class definition.

To quote the documentation:

class definition is an executable statement.

...

The class’s suite is then executed in a new execution frame (see Naming and binding), using a newly created local namespace and the original global namespace. (Usually, the suite contains mostly function definitions.) When the class’s suite finishes execution, its execution frame is discarded but its local namespace is saved. [4] A class object is then created using the inheritance list for the base classes and the saved local namespace for the attribute dictionary. The class name is bound to this class object in the original local namespace.

Some more lengthier explanations.

If you want to call a function to define a class variable, you can do it with one of these ways:

  1. use staticmethod:

    class MyClass:
        def _run_instance_method():
            return "ran instance method"
        run_instance_method = staticmethod(_run_instance_method)
    
        class_var_1 = "a"
        class_var_2 = _run_instance_method() # or run_instance_method.__func__()
    
  2. or define it as a standalone function:

    def run_method():
        return "ran method"
    
    class MyClass:
        class_var_1 = "a"
        class_var_2 = run_method()
    
        # optional
        run_method = staticmethod(run_method)
    
  3. or access the original function with __func__ and provide a dummy cls value:

    class MyClass:
        @classmethod
        def run_class_method(cls):
            return "ran class method"
    
        class_var_1 = "a"
        class_var_2 = run_class_method.__func__(object())
    
  4. or set the class variables after class creation:

    class MyClass:
        @classmethod
        def run_class_method(cls):
            return "ran class method"
    
        class_var_1 = "a"
    
    MyClass.class_var_2 = MyClass.run_class_method()
    
2 of 4
3

MyClass is not yet defined when its class attributes are still being defined, so at the time class_var_2 is being defined, MyClass is not yet available for reference. You can work around this by defining class_var_2 after the MyClass definition block:

class MyClass:
    class_var_1 = "a"

    @classmethod
    def run_class_method(cls):
        return "ran class method"

MyClass.class_var_2 = MyClass.run_class_method()
Top answer
1 of 6
84

No, you cannot. As other answer point out, you can (ab?)use aliasing of mutable objects to achieve a similar effect. However, that's not the same thing as C++ references, and I want to explain what actually happens to avoid any misconceptions.

You see, in C++ (and other languages), a variable (and object fields, and entries in collections, etc.) is a storage location and you write a value (for instance, an integer, an object, or a pointer) to that location. In this model, references are an alias for a storage location (of any kind) - when you assign to a non-reference variable, you copy a value (even if it's just a pointer, it's still a value) to the storage location; when you assign to a reference, you copy to a storage location somewhere else. Note that you cannot change a reference itself - once it is bound (and it has to as soon as you create one) all assignments to it alter not the reference but whatever is referred to.

In Python (and other languages), a variable (and object fields, and entries in collections, etc.) is a just a name. Values are somewhere else (e.g. sprinkled all over the heap), and a variable refers (not in the sense of C++ references, more like a pointer minus the pointer arithmetic) to a value. Multiple names can refer to the same value (which is generally a good thing). Python (and other languages) calls whatever is needed to refer to a value a reference, despite being pretty unrelated to things like C++ references and pass-by-reference. Assigning to a variable (or object field, or ...) simply makes it refer to another value. The whole model of storage locations does not apply to Python, the programmer never handles storage locations for values. All he stores and shuffles around are Python references, and those are not values in Python, so they cannot be target of other Python references.

All of this is independent of mutability of the value - it's the same for ints and lists, for instance. You cannot take a variable that refers to either, and overwrite the object it points to. You can only tell the object to modify parts of itself - say, change some reference it contains.

Is this a more restrictive model? Perhaps, but it's powerful enough most of the time. And when it isn't you can work around it, either with a custom class like the one given below, or (equivalent, but less obvious) a single-element collection.

class Reference:
    def __init__(self, val):
        self._value = val # just refers to val, no copy

    def get(self):
        return self._value

    def set(self, val):
        self._value = val

That still won't allow you to alias a "regular" variable or object field, but you can have multiple variables referring to the same Reference object (ditto for the mutable-singleton-collection alternative). You just have to be careful to always use .get()/.set() (or [0]).

2 of 6
22

No, Python doesn't have this feature.

If you had a list (or any other mutable object) you could do what you want by mutating the object that both x and y are bound to:

>>> x = [7]
>>> y = x
>>> y[0] = 8
>>> print x
[8]

See it working online: ideone

🌐
ITU Online
ituonline.com › blogs › python-class-variables
Python Class Variables: Declaration, Usage, and Practical Examples – ITU Online IT Training
August 3, 2023 - If your Python class variables are behaving strangely, the problem is usually not Python itself. The problem is shared state that was meant to be shared, but got used like per-object data. class declaration python is one of those topics that looks basic until it causes a bug you can’t spot quickly. A single misplaced attribute can affect defaults, counters, object state, and even inheritance behavior across an entire codebase. ... class declaration python refers to defining attributes on the class itself so every instance can share the same value.