Reputation: 294248
Suppose you have a class
instance
that has already been instantiated and you need to attach a function as a method to the class.
class ClassA(object):
def __init__(self):
self.attr1 = 'hello'
self.attr2 = 'world'
def get_attr1(self):
return self.attr1
For whatever reason, we've neglected to create the get_attr2 method.
If we create an instance of ClassA:
a = ClassA()
We could define a function and even call the first parameter self.
def get_attr2(self):
return self.attr2
However, this can only be called like
get_attr2(a)
How do we set up being able to call the function like a method?
a.get_attr2()
Upvotes: 3
Views: 487
Reputation: 10926
In Python 3 you can just define a function (taking a self variable) and bind it to a name in the class, like this:
#! python3
class A:
def b(self):
print("I am b")
def c(self):
print("I am c")
A.c = c # Now A has a method named 'c'
an_a = A()
an_a.b()
an_a.c()
This program prints "I am b" followed by "I am c" as you would expect. This will perhaps not result in the most easily understood program you've ever seen, but it works.
Upvotes: 1
Reputation: 294248
methods are a specific type of function. That type defines how methods behave and specify that they can be called via the dot convention.
To solve this we need to import types
. Then I'll create a simple function to attach any other function as a method to an existing instance.
import types
def attach_method(class_instance, name, function):
if name not in class_instance.__dict__.keys():
class_instance.__dict__[name] = types.MethodType(function, class_instance)
With this i run:
attach_method(a, 'get_attr2', get_attr2)
And that's it.
function
's have no name, so I have to pass a name.
I have classes in which I want methods defined for each of a long list of other classes. I define these other classes in a separate module. These classes are created at a rapid pace. I thought it would be easier to maintain if I read this other module and generated a separate method that gives access to each class inside the module. This may or may not have been the best solution, but it is what motivated me to find a way to do this. I still haven't seen a more succinct way to do this.
Upvotes: 1