Add attribute to python class

Consider the following code:

class Foo(): pass Foo.entries = dict() a = Foo() a.entries['1'] = 1 b = Foo() b.entries['3'] = 3 print(a.entries) 

This will print:

 {'1': 1, '3': 3} 

as entries are added as a static attribute. Is there a way to decapitate a class definition to add new attributes (without using inheritance).

I managed to find the following method, but it looks confusing to me:

 def patch_me(target, field, value): def func(self): if not hasattr(self, '__' + field): setattr(self, '__' + field, value()) return getattr(self, '__' + field) setattr(target, field, property(func)) patch_me(Foo, 'entries', dict) 
+5
source share
1 answer

Typically, attributes are added either by the __init__() function, or after the instance:

 foo = Foo() foo.bar = 'something' # note case 

If you want to do this automatically, inheritance is by far the easiest way:

 class Baz(Foo): def __init__(self): super().__init__() # super() needs arguments in 2.x self.bar = 'something' 

Note that classes should not be displayed at the top level of the Python module. You can declare a class inside a function:

 def make_baz(value): class Baz(Foo): def __init__(self): super().__init__() # super() needs arguments in 2.x self.bar = value() return Baz() 

This example will create a new class every time make_baz() called. This may or may not be what you want. It would be easier to just do this:

 def make_foo(value): result = Foo() result.bar = value() return result 

If you are really determined to fix the original class with a monkey, the code example you provided is a more or less simple way to do this. You can use the decorator syntax for property() , but this is a small change. I should also note that it will not refer to double underscore of the name, which is probably good because it means that you cannot conflict with any names used by the class itself.

+1
source

All Articles