#Use the setattr Function

class Example:
   a = "Pynerds"

#set a variable attribute to the class
setattr(Example, "b", "Python")
setattr(Example, "c", "Django")

def example_method():
    print("Hello, World!")

#set a method attribute to the class
setattr(Example, "example_method", example_method)

print(Example.a)
print(Example.b)
print(Example.c)

Example.example_method()

The setattr() function is used to  dynamically set the value of an object's attribute. This function is most commonly used for adding a new attribute to an instance of a class, but can also be used with any other type of object. It can be used as an alternative to attribute assignment ( i.e MyClass.some_attribute = value)

setattr(obj, name, value)

obj

Specifies the object on which to set the attribute.
name Specifies the name of the attribute to be set.

value

Specifies value of the attribute to be set.

The function sets the attribute to the specified object and returns None. If an attribute already exists with a similar name, its value will be overwritten.

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age 

stu = Student('John', 20)

print("Name:", stu.name)
print("Age:", stu.age)

# Setting the attribute value
setattr(stu, 'name', 'David')

print("Name:", stu.name)
class Person():
    def __init__(self, fname, lname):
        self.fname = fname
        self.lname = lname

def _str(self):
   return f'my name is {self.fname} {self.lname}'

setattr(Person, '__str__', _str)

p = Person('John', 'Doe')
print(p)

The setattr function may be  helpful  in some cases, however, It should be used only when necessary.  Using the function unnecessarily can lead to debugging issues.It can also be slow, as it has to traverse the class hierarchy to find the attribute being set. 

Whenever possible,  it is more preferable to use a more explicit approach when setting class attributes such as creating attributes in the class definition and using assignment to set values.