Berke Balcı
Berke Balcı

Reputation: 93

How can i add atrributes to the class method from outside class?

This is gonna be my first question on this website. If I do mistake about English, sorry. Okey, my question is how can I add or set attribute to the class method from outside class?

If i am not wrong,we use settatr() to do this. Can you guys help me pls?

class sss():
   def __init__(self,name,surname):
       self.name = name
       self.surname = surname
   def method1(self):
       a = "Python"

When we do this:

object = sss("Adam","Roger") #This 2 lines are on outside the class
setattr(object,"Age",19)

What exactly happens? Now this "Age" attribute belong to our object? What is the value of the "Age" attribute now? I mean is that class attribute or what?

My second question is how can I add attribute to the class method?

Thank you

Upvotes: 2

Views: 2252

Answers (4)

C-3PO
C-3PO

Reputation: 1213

As @Julian Fock mentioned, you can add attributes to an object by simply writing statements, such as person.age = 19. Your instance/object of the sss-Person class would now have this attribute, but not the class itself.

To modify the class sss-Person itself, you would need to implement some ugly methods, which would be labelled as "hacky" or "bad practices" by most programmers. Companies could refuse to accept the code as valid. You should instead consider using other methods such as class inheritance, where you can derive a modified class adding more advanced functionality.

Still, changing a class definition can be useful for debugging or exceptional emergencies. In that case, you can define external functions, and link them to override your class methods as follows:

# A) Initial Analysis

class Person:
   def __init__(self,name,surname):
       self.name    = name
       self.surname = surname
   def method1(self):
       a = "Python"

person1 = Person("Adam","Roger")
person2 = Person("Adam","Roger")

person1.age = 19

print(person1.age)
# Output: 19

# print(person2.age)
# AttributeError: 'Person' object has no attribute 'age'

# B) Change class attributes

def __init2__(self, name, surname, age):
    self.name    = name
    self.surname = surname
    self.age     = age

Person.__init__ = __init2__

person3 = Person("Adam","Roger", 20)

print(person3.age)
# Output: 20

# person4 = Person("Adam","Roger")
# TypeError: __init2__() missing 1 required positional argument: 'age'


# C) Overwrite method1

def method2(self):
    self.a = "Python"

Person.method1 = method2

person5 = Person("Adam","Roger",44)
person5.method1()
print(person5.a)
# Output: "Python"

Upvotes: 0

Tonsic
Tonsic

Reputation: 1138

PS.: I will not get into the merit of wether it is recommended to do things that I will exemplify here.

Adding to Bill Lynch's answer

What is "Age" attribute now? I mean is that class attribute or what?

Age is now an instance variable on your instance of sss named object.

PS.: Don't use object for it is a keyword in python.

What is the value of the "Age" attribute now?

The value is 19.

I mean is that class attribute or what?

It is a attribute of the instance you created from the class, and only for that instance.

how can I add attribute to the class method?

If you want to add the attribute to the class so that every instance has a new attribute of your choosing, you can do this:

    setattr(sss, 'b', 'Python')

    obj1 = sss("Adam", "Roger")
    print(obj1.b)

    obj2 = sss("Adam", "Roger")
    print(obj2.b)

    obj2.b = "New"

    print(obj1.b) # will still be Python
    print(obj2.b) # now will be New

If you want to overwrite method1 with a new method:

    sss_obj = sss("Adam", "Roger")

    def method1(self):
        self.b = 'New'

    setattr(sss, 'method1', method1)

    print('Should be False because the instance has no b attribute yet.', hasattr(sss_obj, 'b'))

    sss_obj.method1()

    print('Now it has and b value is', sss_obj.b)

If you want to change the method on a specific instance of class sss:

    sss_obj = sss("Adam", "Roger")
    sss_obj2 = sss("Adam", "Roger")

    def method1():
        sss_obj2.b = 'New'

    setattr(sss_obj2, 'method1', method1)

    sss_obj.method1()
    print('Should be False because method1 from instance sss_obj does not set b.', hasattr(sss_obj, 'b'))

    sss_obj2.method1()
    print('Now on instance 2 the b value is', sss_obj2.b)

If you want to change the source of the method as a string programatically:

    sss_obj = sss("Adam", "Roger")

    new_method_source = 'self.b = "NotRecommended"\n' \
                        'print("Got into changed method")'

    def method1(self):
        return exec(
            compile(new_method_source, '', mode='exec'),
            None,
            {
                'self': self
            }
        )

    setattr(sss, 'method1', method1)

If you want to change the code from method1, first grab the source with the following line

method1_src = inspect.getsource(sss_obj.method1)

Then change the string as you will and do a similar thing as previously mentioned (compile and stuff).

Cheers

Upvotes: 0

Julian Fock
Julian Fock

Reputation: 108

If you instanciate your class with e.g. person = Sss("Adam", "Roger") you can access and add attributes with a dot like this:

person.age = 19

Full example:

class Sss:
    # You should name your class with capital letter and without brackets
    def __init__(self, name, surname):
        self.name = name
        self.surname = surname


person = Sss("Adam", "Roger")
print(person.name) # access attribute

person.age = 19 # add attribute
print(person.age)

Upvotes: 2

Bill Lynch
Bill Lynch

Reputation: 81976

What is "Age" attribute now? I mean is that class attribute or what?

Age is now an instance variable on your instance of sss named object.

How can i add attribute to the class method?

I'm not sure what you're asking for here.

Upvotes: 0

Related Questions