The Python docs say all that needs to be said, as far as I can see.

setattr(object, name, value)

This is the counterpart of getattr(). The arguments are an object, a string and an arbitrary value. The string may name an existing attribute or a new attribute. The function assigns the value to the attribute, provided the object allows it. For example, setattr(x, 'foobar', 123) is equivalent to x.foobar = 123.

Answer from Chris Morgan on Stack Overflow
Discussions

Why `self.__setattr__(attr, value)` trigger `__getattribute__`?
In the following example,when the code run to the line self.__setattr__(attr, value),the self.__setattr__ in the line invoke __getattribute__,maybe python interpreter just read part of code: import time class Room: def __init__(self,name): self.name = name def __getattribute__(self,attr): print('in ... More on discuss.python.org
🌐 discuss.python.org
0
0
August 6, 2023
python - How to use __setattr__ correctly, avoiding infinite recursion - Stack Overflow
This is also mentioned in the Python docs. 2018-12-07T18:13:19.49Z+00:00 ... @Bakuriu would you please explain what this line is doing exactly? super(MyTest, self).__setattr__(name, value) 2020-04-01T07:03:17.353Z+00:00 More on stackoverflow.com
🌐 stackoverflow.com
Why used setattr/getattr instead of writing my own methods?
You wouldn't use them in code like this at all. You'd use them when you wanted to dynamically set or get an attribute using a string. But note you shouldn't be writing code like this in the first place. There's no reason to write simple getter or setter methods at all, just access the attributes directly. More on reddit.com
🌐 r/learnpython
16
2
March 13, 2022
python - How does __setattr__ work with class attributes? - Stack Overflow
I had actually tried something ... the self.__dict__get('initialized') and I ended up throwing the error when I attempted to set my Boolean value. The other reason I had moved away from these types of approaches is that I wanted to use the attribute externally in places where I did not always have an instance of the class. That may not be good python programming practice though. I am still relatively new to the language so I am not sure. 2016-09-26T18:09:52.03Z+00:00 ... __setattr__ is only ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
GeeksforGeeks
geeksforgeeks.org › python-setattr-method
Python setattr() method - GeeksforGeeks
June 19, 2023 - Python setattr() method is used to assign the object attribute its value. The setattr() can also be used to initialize a new object attribute. Also, setattr() can be used to assign None to any object attribute.
🌐
Python Morsels
pythonmorsels.com › python-setattr
Python's setattr function and __setattr__ method - Python Morsels
June 9, 2022 - Let's talk about Python's built-in setattr function. ... Our Row class is supposed to accept any number of keyword arguments and assign each of them to an attribute on a new Row object. We can use Python's ** operator to capture arbitrary keyword arguments into a dictionary: class Row: def __init__(self, **attributes): for attribute, value in attributes.items(): ...
🌐
Python.org
discuss.python.org › python help
Why `self.__setattr__(attr, value)` trigger `__getattribute__`? - Python Help - Discussions on Python.org
August 6, 2023 - In the following example,when the code run to the line self.__setattr__(attr, value),the self.__setattr__ in the line invoke __getattribute__,maybe python interpreter just read part of code: import time class Room: def __init__(self,name): self.name = name def __getattribute__(self,attr): print('in __getattribute__',attr) return object.__getattribute__(self,attr) def __setattr__(self,attr,value): print('in __setattr__',attr) time.sleep(3) ...
🌐
AskPython
askpython.com › home › python setattr() function
Python setattr() Function - AskPython
February 16, 2023 - Let us look at how we could use this function in our Python programs. It takes the object name, the attribute name and the value as the parameters, and sets object.attribute to be equal to value. Since any object attribute can be of any type, no exception is raised by this function. ... Here is a simple example to demonstrate the use of setattr(). class MyClass(): def __init__(self...
🌐
Real Python
realpython.com › ref › builtin-functions › setattr
setattr() | Python’s Built-in Functions – Real Python
Instead, it modifies the input object by setting the specified attribute to the given value. ... >>> class Car: ... def __init__(self, make, model): ... self.make = make ... self.model = model ...
🌐
W3Schools
w3schools.com › python › ref_func_setattr.asp
Python setattr() Function
Python Examples Python Compiler Python Exercises Python Quiz Python Challenges Python Server Python Syllabus Python Study Plan Python Interview Q&A Python Bootcamp Python Certificate Python Training ... class Person: name = "John" age = 36 country = "Norway" setattr(Person, 'age', 40) Try it Yourself »
Find elsewhere
🌐
Programiz
programiz.com › python-programming › methods › built-in › setattr
Python setattr()
# setting name to 'John' setattr(p, 'name', 'John') print('After modification:', p.name)
🌐
Python Morsels
pythonmorsels.com › __setattr__
Python's __setattr__ method - Python Morsels
June 4, 2024 - The Python documentation for object.__setattr__ also notes this approach for invoking Python's low-level assignment setting mechanism. Note that when implementing __setattr__, you'll need to make sure not to call your own __setattr__ method. ... class LowerAttributes: def __getattr__(self, name): return getattr(self, name.casefold()) def __setattr__(self, name, value): return setattr(self, name.casefold(), value)
🌐
Finxter
blog.finxter.com › python-setattr
Python setattr() – Be on the Right Side of Change
The difference is that the setattr() requires a string value of the attribute name while the assignment operation requires the name of the attribute itself. Thus, if you have only the textual representation of the attribute to be set—for example, from a dictionary of key value pairs—you ...
🌐
Sololearn
sololearn.com › en › Discuss › 2756004 › setattr-vs-regular-assignment
setattr() vs. Regular Assignment | Sololearn: Learn to code for FREE!
I recently learned about the setattr() function in Python. What makes this function different than just assigning the new attribute? Like this: # setattr() class Thing: def __init__(self, x): self.x = x something = Thing(5) setattr(something, 'y', 10) # Adds a 'y' attribute to 'something' # vs.
🌐
Toppr
toppr.com › guides › python-guide › references › methods-and-functions › python-setattr
Python setattr() Function: What is setattr in Python used for?
November 10, 2021 - One of the most important properties of setattr() is that it can be used to create and initialize a new attribute in the object if it is not found. We can assign the ‘None’ value to the attribute.
🌐
Reddit
reddit.com › r/learnpython › why used setattr/getattr instead of writing my own methods?
r/learnpython on Reddit: Why used setattr/getattr instead of writing my own methods?
March 13, 2022 -

Hello fellow pythoners!

I was introduced to the built-in function setattr() and getattr() functions today in regards to classes and started to question why I would want to use these functions instead of writing my own get_attribute and set_attribute methods.

So yeah, why? All my searches just gave me explanations as to how they're used, not why to use it instead of what I was taught back in school.

Is writing my own methods just a translation to how to handle this from someone who came from a language such as java or C# to setting and getting attributes?

Edit: Code example below

class Student:
  def __init__(self, name, grade):
      self.name = name
      self.grade = grade
  def get_name(self):
      return self.name
  def get_grade(self):
      return self.grade
  def set_name(self, name):
      self.name = name
  def set_grade(self, grade):
      self.grade = grade

class Person:
   def __init__(self, name, addr):
      self.name = name
      self.address = addr
   
if __name__ == "__main__":
   george = Student("George", "B")
   jessica = Person("Jessica", "221B Baker Steet")
   print(f"{george.get_name()} has a {george.get_grade()} in English.")
   george.set_grade("A")
   print(f"{george.get_name()} now has a {george.get_grade()} in English")

   print(f"{getattr(jessica, name)} lives on {getattr(jessica, address)}.")
   setattr(jessica, address, "Abbey Road 5")
   print(f"{getattr(jessica, name)} now lives on {getattr(jessica, address)}
🌐
Reintech
reintech.io › blog › python-mastering-the-setattr-and-getattr-methods-tutorial
Python: Mastering the setattr() and getattr() Methods | Reintech media
March 24, 2023 - The setattr() function sets an attribute value on an object using a string-based name. This is functionally equivalent to using dot notation, but with the crucial advantage of accepting dynamic attribute names.
🌐
datagy
datagy.io › home › python posts › python setattr() function explained
Python setattr() Function Explained • datagy
May 6, 2022 - # Understanding the Python setattr() Function setattr( object, # The object to set the attribute on name, # The name of the attribute value # The value of the attribute ) We can see that the function takes three parameters: the object itself, the name of the attribute, and the value to be set. Let’s take a look at how we can use the function to set an attribute’s value: # Setting the attribute of an object class Employee: def __init__(self, name, salary): self.name = name self.salary = salary Nik = Employee("Nik", 75000) print('Before changing attribute...') print('Nik.salary:', Nik.salary) setattr(Nik, "salary", 80000) print('After changing attribute...') print('Nik.salary:', Nik.salary) # Returns: # Before changing attribute...
Top answer
1 of 5
16

__setattr__() applies only to instances of the class. In your second example, when you define PublicAttribute1, you are defining it on the class; there's no instance, so __setattr__() is not called.

N.B. In Python, things you access using the . notation are called attributes, not variables. (In other languages they might be called "member variables" or similar.)

You're correct that the class attribute will be shadowed if you set an attribute of the same name on an instance. For example:

class C(object):
    attr = 42

 c = C()
 print(c.attr)     # 42
 c.attr = 13
 print(c.attr)     # 13
 print(C.attr)     # 42

Python resolves attribute access by first looking on the instance, and if there's no attribute of that name on the instance, it looks on the instance's class, then that class's parent(s), and so on until it gets to object, the root object of the Python class hierarchy.

So in the example above, we define attr on the class. Thus, when we access c.attr (the instance attribute), we get 42, the value of the attribute on the class, because there's no such attribute on the instance. When we set the attribute of the instance, then print c.attr again, we get the value we just set, because there is now an attribute by that name on the instance. But the value 42 still exists as the attribute of the class, C.attr, as we see by the third print.

The statement to set the instance attribute in your __init__() method is handled by Python like any code to set an attribute on an object. Python does not care whether the code is "inside" or "outside" the class. So, you may wonder, how can you bypass the "protection" of __setattr__() when initializing the object? Simple: you call the __setattr__() method of a class that doesn't have that protection, usually your parent class's method, and pass it your instance.

So instead of writing:

self.PublicAttribute1 = "attribute"

You have to write:

 object.__setattr__(self, "PublicAttribute1", "attribute")

Since attributes are stored in the instance's attribute dictionary, named __dict__, you can also get around your __setattr__ by writing directly to that:

 self.__dict__["PublicAttribute1"] = "attribute"

Either syntax is ugly and verbose, but the relative ease with which you can subvert the protection you're trying to add (after all, if you can do that, so can anyone else) might lead you to the conclusion that Python doesn't have very good support for protected attributes. In fact it doesn't, and this is by design. "We're all consenting adults here." You should not think in terms of public or private attributes with Python. All attributes are public. There is a convention of naming "private" attributes with a single leading underscore; this warns whoever is using your object that they're messing with an implementation detail of some sort, but they can still do it if they need to and are willing to accept the risks.

2 of 5
8

The __setattr__ method defined in a class is only called for attribute assignments on instances of the class. It is not called for class variables, since they're not being assigned on an instance of the class with the method.

Of course, classes are instances too. They're instances of type (or a custom metaclass, usually a subclass of type). So if you want to prevent class variable creation, you need to create a metaclass with a __setattr__ method.

But that's not really what you need to make your class do what you want. To just get a read-only attribute that can only be written once (in the __init__ method), you can probably get by with some simpler logic. One approach is to set another attribute at the end of the __init__ method, which tells __setattr__ to lock down assignments after it is set:

class Foo:
    def __init__(self, a, b):
        self.a = a
        self.b = b
        self._initialized = True

    def __setattr__(self, name, value):
        if self.__dict__.get('_initialized'):
            raise Exception("Attribute is Read-Only")
        super().__setattr__(name, value)

Another option would be to use property descriptors for the read-only attributes and store the real values in "private" variables that can be assigned to normally. You'd not use __setattr__ in this version:

class Foo:
    def __init__(self, a, b):
        self._a = a
        self._b = b

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

    @property
    def b(self):
        return self._b

foo = Foo(3, 5)
foo.a = 7 # causes "AttributeError: can't set attribute"
🌐
Javatpoint
javatpoint.com › python-setattr-function
Python setattr() function with Examples - Javatpoint
We are excited to announce that we are moving from JavaTpoint.com to TpointTech.com on 10th Feb 2025. Stay tuned for an enhanced experience with the same great content and even more features. Thank you for your continued support · Python setattr() function is used to set a value to the object's ...
🌐
GitConnected
levelup.gitconnected.com › decoding-python-magic-setattr-fe017375bb64
Decoding Python Magic : __setattr__ | by Rahul Beniwal | Level Up Coding
March 14, 2024 - class MyClass: def __setattr__(self, name, value): # Set the attribute directly on the instance self.__dict__[name] = value obj = MyClass() obj.attr = 42 · In conclusion, __setattr__ is a powerful method in Python that allows you to define custom behavior for setting attribute values on an object.