Extending bp's answer, I wanted to show you what he meant by immutable types.

First, this is okay:

>>> class TestB():
...     def __init__(self, attr=1):
...         self.attr = attr
...     
>>> a = TestB()
>>> b = TestB()
>>> a.attr = 2
>>> a.attr
2
>>> b.attr
1

However, this only works for immutable (unchangable) types. If the default value was mutable (meaning it can be replaced), this would happen instead:

>>> class Test():
...     def __init__(self, attr=[]):
...         self.attr = attr
...     
>>> a = Test()
>>> b = Test()
>>> a.attr.append(1)
>>> a.attr
[1]
>>> b.attr
[1]
>>> 

Note that both a and b have a shared attribute. This is often unwanted.

This is the Pythonic way of defining default values for instance variables, when the type is mutable:

>>> class TestC():
...     def __init__(self, attr=None):
...         if attr is None:
...             attr = []
...         self.attr = attr
...     
>>> a = TestC()
>>> b = TestC()
>>> a.attr.append(1)
>>> a.attr
[1]
>>> b.attr
[]

The reason my first snippet of code works is because, with immutable types, Python creates a new instance of it whenever you want one. If you needed to add 1 to 1, Python makes a new 2 for you, because the old 1 cannot be changed. The reason is mostly for hashing, I believe.

Answer from Xavier Ho on Stack Overflow
Top answer
1 of 6
187

Extending bp's answer, I wanted to show you what he meant by immutable types.

First, this is okay:

>>> class TestB():
...     def __init__(self, attr=1):
...         self.attr = attr
...     
>>> a = TestB()
>>> b = TestB()
>>> a.attr = 2
>>> a.attr
2
>>> b.attr
1

However, this only works for immutable (unchangable) types. If the default value was mutable (meaning it can be replaced), this would happen instead:

>>> class Test():
...     def __init__(self, attr=[]):
...         self.attr = attr
...     
>>> a = Test()
>>> b = Test()
>>> a.attr.append(1)
>>> a.attr
[1]
>>> b.attr
[1]
>>> 

Note that both a and b have a shared attribute. This is often unwanted.

This is the Pythonic way of defining default values for instance variables, when the type is mutable:

>>> class TestC():
...     def __init__(self, attr=None):
...         if attr is None:
...             attr = []
...         self.attr = attr
...     
>>> a = TestC()
>>> b = TestC()
>>> a.attr.append(1)
>>> a.attr
[1]
>>> b.attr
[]

The reason my first snippet of code works is because, with immutable types, Python creates a new instance of it whenever you want one. If you needed to add 1 to 1, Python makes a new 2 for you, because the old 1 cannot be changed. The reason is mostly for hashing, I believe.

2 of 6
83

The two snippets do different things, so it's not a matter of taste but a matter of what's the right behaviour in your context. Python documentation explains the difference, but here are some examples:

Exhibit A

class Foo:
  def __init__(self):
    self.num = 1

This binds num to the Foo instances. Change to this field is not propagated to other instances.

Thus:

>>> foo1 = Foo()
>>> foo2 = Foo()
>>> foo1.num = 2
>>> foo2.num
1

Exhibit B

class Bar:
  num = 1

This binds num to the Bar class. Changes are propagated!

>>> bar1 = Bar()
>>> bar2 = Bar()
>>> bar1.num = 2 #this creates an INSTANCE variable that HIDES the propagation
>>> bar2.num
1
>>> Bar.num = 3
>>> bar2.num
3
>>> bar1.num
2
>>> bar1.__class__.num
3

Actual answer

If I do not require a class variable, but only need to set a default value for my instance variables, are both methods equally good? Or one of them more 'pythonic' than the other?

The code in exhibit B is plain wrong for this: why would you want to bind a class attribute (default value on instance creation) to the single instance?

The code in exhibit A is okay.

If you want to give defaults for instance variables in your constructor I would however do this:

class Foo:
  def __init__(self, num = None):
    self.num = num if num is not None else 1

...or even:

class Foo:
  DEFAULT_NUM = 1
  def __init__(self, num = None):
    self.num = num if num is not None else DEFAULT_NUM

...or even: (preferrable, but if and only if you are dealing with immutable types!)

class Foo:
  def __init__(self, num = 1):
    self.num = num

This way you can do:

foo1 = Foo(4)
foo2 = Foo() #use default
Discussions

python - Setting default values in a class - Stack Overflow
I am creating a class in Python, and I am unsure how to properly set default values. My goal is to set default values for all class instances, which can also be modified by a class method. However, I More on stackoverflow.com
🌐 stackoverflow.com
A way to have the default value for a parameter as the default of another function: the Default singleton - Ideas - Discussions on Python.org
Often, I use the defaults of another function in my new function or class. For example: def mysorted(it, key=None, reversed=False): # some code return sorted(it, key=key, reversed=reversed) The majority of times I want to simply adhere to the sign of the original function. More on discuss.python.org
🌐 discuss.python.org
1
September 7, 2022
Understand the behavior of default params in python classes
What I’m trying to do: Understand the behavior of default params in python classes. I made a sort of random change to the class init, which achieves the behavior I want, but I don’t understand why it does. What I’ve tried and what’s not working: Originally in the Week Custom component ... More on anvil.works
🌐 anvil.works
0
0
September 30, 2021
python - How to assign "default" values in class? - Stack Overflow
Communities for your favorite technologies. Explore all Collectives · Stack Overflow for Teams is now called Stack Internal. Bring the best of human thought and AI automation together at your work More on stackoverflow.com
🌐 stackoverflow.com
🌐
Python Examples
pythonexamples.org › python-default-values-for-properties-in-class
Set Default Values for Properties in Class in Python
We can set default values for properties in the class definition, either by assigning the properties with the default values inside the class, or by specifying optional arguments in __init__() function definition.
🌐
Bruceeckel
bruceeckel.com › 2022 › 05 › 11 › misunderstanding-python-class-attributes
Misunderstanding Python Class Attributes
May 11, 2022 - Imagine these kinds of errors appearing in your code base, and trying to track them down based on the varying behavior of these so-called “default values.” ... Python’s dynamic nature. Instance variables are not automatically created, not even in the constructor. They are created the first time they are assigned to, which can happen just about anywhere. Unlike C++ and Java, Python allows instance variables to shadow (have the same name as) class attributes.
🌐
Rip Tutorial
riptutorial.com › default values for instance variables
Python Language Tutorial => Default values for instance variables
This behavior is caused by the fact that in Python default parameters are bound at function execution and not at function declaration. To get a default instance variable that's not shared among instances, one should use a construct like this: class Rectangle2D(object): def __init__(self, width, height, pos=None, color='blue'): self.width = width self.height = height self.pos = pos or [0, 0] # default value is [0, 0] self.color = color r1 = Rectangle2D(5,3) r2 = Rectangle2D(7,8) r1.pos[0] = 4 r1.pos # [4, 0] r2.pos # [0, 0] r2's pos hasn't changed
🌐
Abdul Wahab Junaid
awjunaid.com › home › default values for instance variables in python
Default values for instance variables in python | Abdul Wahab Junaid
August 14, 2023 - When you create instances of the class, you can provide values for both name and age, or just for name, in which case age will default to 18.
Top answer
1 of 3
4

There is a whole bunch of ways to solve this problem, but if you have python 3.7 installed (or have 3.6 and install the backport), dataclasses might be a good fit for a nice solution.

First of all, it lets you define the default values in a readable and compact manner, and also allows all the mutation operations you need:

>>> from dataclasses import dataclass
>>> @dataclass
... class Plots:
...     a: int = 1
...     b: int = 2
...     c: int = 3
...     
>>> p = Plots()        # create a Plot with only default values
>>> p
Plots(a=1, b=2, c=3)
>>> p.a = -1           # update something in this Plot instance
>>> p
Plots(a=-1, b=2, c=3)

You also get the option to define default factories instead of default values for free with the dataclass field definition. It might not be a problem yet, but it avoids the mutable default value gotcha, which every python programmer runs into sooner or later.

Last but not least, writing a reset function is quite easy given an existing dataclass, because it keeps track of all the default values already in its __dataclass_fields__ attribute:

>>> from dataclasses import dataclass, MISSING
>>> @dataclass
... class Plots:
...     a: int = 1
...     b: int = 2
...     c: int = 3
... 
...     def reset(self):
...         for name, field in self.__dataclass_fields__.items():
...             if field.default != MISSING:
...                 setattr(self, name, field.default)
...             else:
...                 setattr(self, name, field.default_factory())
...
>>> p = Plots(a=-1)     # create a Plot with some non-default values  
>>> p
Plots(a=-1, b=2, c=3)
>>> p.reset()           # calling reset on it restores the pre-defined defaults
>>> p
Plots(a=1, b=2, c=3)

So now you can write some function do_stuff(...) that updates the fields in a Plot instance, and as long as you execute reset() the changes won't persist.

2 of 3
2

You can use class variables, and property to achieve your goal to set default values for all class instances. The instances values can be modified directly, and the initial default values restored after calling a method.

In view of the context that "the real class has dozens of default values", another approach that you may consider, is to set up a configuration file containing the default values, and using this file to initialize, or reset the defaults.

Here is a short example of the first approach using one class variable:

class Plots:

    _a = 1

    def __init__(self):
        self._a = None
        self.reset_default_values()

    def reset_default_values(self):
        self._a = Plots._a

    @property
    def a(self):
        return self._a

    @a.setter
    def a(self, value):
        self._a = value


plot = Plots()
print(plot.a)

plot.a = 42
print(plot.a)

plot.reset_default_values()
print(plot.a)

output:

1
42
1
Find elsewhere
🌐
Python.org
discuss.python.org › ideas
A way to have the default value for a parameter as the default of another function: the Default singleton - Ideas - Discussions on Python.org
September 7, 2022 - Often, I use the defaults of another function in my new function or class. For example: def mysorted(it, key=None, reversed=False): # some code return sorted(it, key=key, reversed=reversed) The majority of time…
🌐
pythontutorials
pythontutorials.net › blog › how-should-i-declare-default-values-for-instance-variables-in-python
How to Declare Default Values for Instance Variables in Python: Class vs __init__ – Which is More Pythonic?
Python offers two primary ways to declare default values for instance variables: 1. **Class-level declaration**: Assigning the default directly in the class body (outside the `__init__` method).
🌐
YouTube
youtube.com › watch
How to Initialize Variables of the Class with Default Values in Python - YouTube
How to Initialize Variables of the class with Default ValuesHere we are initializing variables inside the class with default values.=========================...
Published: October 28, 2020
🌐
Anvil
anvil.works › anvil q&a
Understand the behavior of default params in python classes - Anvil Q&A - Anvil Community Forum
September 30, 2021 - What I’m trying to do: Understand the behavior of default params in python classes. I made a sort of random change to the class init, which achieves the behavior I want, but I don’t understand why it does. What I’ve tried and what’s not working: Originally in the Week Custom component the init looked like: def __init__(self, week_number, days = [], **properties): self.days = days self.week_number = week_number self.init_components(**properties) When printing the length of the ...
🌐
Stack Overflow
stackoverflow.com › questions › 74737652 › how-to-assign-default-values-in-class
python - How to assign "default" values in class? - Stack Overflow
Let's assume the user input is correct, why does the input not match? How can I set the value of playClass in the constructor? class player(): playClass = None items = [] level = 1 def __init__(self) -> None: x = input('Welcome!
🌐
Real Python
realpython.com › lessons › advanced-default-values
Advanced Default Values (Video) – Real Python
In the Position example, you saw how to add simple default values by writing lat: float = 0.0. However, if you also want to customize the field, for instance to hide it in the repr, you need to use the default parameter as seen onscreen. 04:25 You may not specify both default and default_factory. The metadata parameter is not used by the data classes themselves but is available for you or third party packages to attach information to fields.
Published: September 14, 2021
🌐
Reddit
reddit.com › r/learnpython › class init method: best way for default value assignments
r/learnpython on Reddit: class init method: best way for default value assignments
December 18, 2021 -

I am learning linked lists in python using classes.

One place that I am learning from is doing:

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

The other place is doing:

class Node:
    def __init__(self, value, next = None):
        self.value = value
        self.next = next

I can't figure out what difference it makes to use either init method. I tried to search this answer out using StackOverflow, but I had no luck.

I get that one is able to define 'next' during instantiation and the other would need to be defined after instantiation, but when would and why would you use one over the other?

edit: Thanks all. I am just starting to understand classes and still overthinking a little.

🌐
TechAlmirah
techalmirah.com › python › default values in python
Default Values in Python: Simplify Your Data Classes
August 19, 2025 - from dataclasses import dataclass @dataclass class Book: title: str = "Untitled" author: str = "Unknown" pages: int = 0 price: float = 0.0 · Here, each attribute is assigned a default value.
Top answer
1 of 2
4

Some minor comments on the code:

  1. Class definition should be separated from the line with import by two spaces.
  2. My personal preference is to have key-value pairs in dictionaries separated with a space after colon as shown in PEP 8:

    defaults = {'A': None, 'B': 0, 'C': 0}
    
  3. Comparing to None should be done by is instead of ==:

    required = [key for key, value in defaults.items() if value is None]
    

    Note that I also removed redundant brackets around key, value. There are several other lines where brackets are not needed around them.

  4. PEP 8 also discourages aligning several lines with assignments by =, so instead of, for example:

    results        = None
    keys, values   = zip(*setup.items())
    

    it should be

    results = None
    keys, values = zip(*setup.items())
    
  5. There is no need to specify object in class O(object), class O will work fine.

  6. Here:

    for key, value in kwargs.items():
        if key in setup:
            setup[key] = kwargs[key]  # user specified overrides default
    

    you don't use value, but you could:

    for key, value in kwargs.items():
        if key in setup:
            setup[key] = value
    
  7. Here:

    keys, values = zip(*setup.items())

    you don't need values as you overwrite them later. So, I'd just remove this line altogether.

  8. set((1,)) can be replaced with {1}, and set.difference can be replaced with just -. BTW, I like how you combined two conditions from my previous review in one!

  9. Don't forget to use np.can_cast instead of checking the dtypes against np.int64. The current version failed for me until I changed it.

  10. [array.astype(float) for array in arrays] can be written as list(map(np.float64, arrays)) but both versions are fine.

  11. The overall design looks quite unusual to me. If it would be me, I'd separate validating data from the container that will keep it. In other words, I'd not keep it in one class. BTW, if a class has just two methods and one of them is __init__ then it shouldn't be a class. Another thing you could try is pydantic library. Never had a chance to try it myself though, but with this problem of data validation I'd give it a shot.

2 of 2
3

If there are required parameters, you should state them explicitly.

class O:

    def __init__(self, A=None, B=0, C=0, **kwargs):

By all means I would advise stronly against your solution. Class members should be clearly readable.

🌐
Real Python
realpython.com › python-data-classes
Data Classes in Python (Guide) – Real Python
March 18, 2026 - Dataclasses allow you to create classes quickly, but you can also add defaults, custom methods, ordering, immutability, inheritance, and even slots. By the end of this tutorial, you’ll understand that: Mutable defaults use field(default_factory=...), while simple defaults use field(default=...) or an inline value.