How to Inject Methods into Python Classes with Decorators
I wanted to know if I could use decorators in Python to add a function to a class as a method of that class. Turns out you can add any function (not methods though, still working on that) to a class by just passing the name of the function with the "inject" functions I wrote. We can add functions as static methods, class methods, or instance methods to our classes.
Here's a great article on how Python decorators work in case you know nothing: Primer on Python Decorators
def injector_model(function, mod=None):
name = function.__name__
def wrapper(k):
if mod == None:
setattr(k, name, eval(name))
else:
setattr(k, name, mod(eval(name)))
return k
return wrapper
def inject_static_method(function):
return injector_model(function, staticmethod)
def inject_class_method(function):
return injector_model(function, classmethod)
def inject_instance_method(function):
return injector_model(function)
def static_test():
print("I'm static")
def class_test(cls):
print(cls)
def instance_test(self):
print(self)
@inject_static_method(static_test)
@inject_class_method(class_test)
@inject_instance_method(instance_test)
class TestClass:
pass
The three decorators here can be in any order and each inject their function into the class that can be called up when needed.
TestClass.static_test()
#prints -> I'm static
TestClass.class_test()
#prints -> <class '__main__.TestClass'>
tc = TestClass()
tc.instance_test()
#prints -> <__main__.TestClass object at 0x00000051B>
All the code is in my github here.
Here's a great article on how Python decorators work in case you know nothing: Primer on Python Decorators
The Injector Model
This function is most of the code that gets reused by the inject functions. It uses the setattr function to add the passed function to the class that you decorate and depending on which mod you use (staticmethod, classmethod) or not, it establishes the type of method defined.
def injector_model(function, mod=None):
name = function.__name__
def wrapper(k):
if mod == None:
setattr(k, name, eval(name))
else:
setattr(k, name, mod(eval(name)))
return k
return wrapper
The Inject Functions
These are the functions we will use to decorate our class.
def inject_static_method(function):
return injector_model(function, staticmethod)
def inject_class_method(function):
return injector_model(function, classmethod)
def inject_instance_method(function):
return injector_model(function)
Let's Inject Some Functions
Here are some test functions we will add to our empty test class. Notice that the class_test needs a "cls" parameter while the instance_test needs a "self" parameter in order to work properly.def static_test():
print("I'm static")
def class_test(cls):
print(cls)
def instance_test(self):
print(self)
@inject_static_method(static_test)
@inject_class_method(class_test)
@inject_instance_method(instance_test)
class TestClass:
pass
The three decorators here can be in any order and each inject their function into the class that can be called up when needed.
Finally We Call the Injected Functions
Both the static method and the class method do not need an instance of the class to call them while the instance method we added first needs an instance object to be created in order to call it.
TestClass.static_test()
#prints -> I'm static
TestClass.class_test()
#prints -> <class '__main__.TestClass'>
tc = TestClass()
tc.instance_test()
#prints -> <__main__.TestClass object at 0x00000051B>
All the code is in my github here.
After a long time, I read a very beautiful and very important article that I enjoyed reading. I have found that this article has many important points, I sincerely thank the admin of this website for sharing it.
ReplyDeletepython training in hyderabad
ReplyDeleteThis is really a good source of information, I will often follow it to know more information and expand my knowledge, I think everyone should know it, thanks Best osi model service provider.
Casinos Near Harrah's Casino And Earth Tower - Mapyro
ReplyDeleteThe cheapest way to get 고양 출장안마 from 삼척 출장마사지 Harrah's Casino And Earth Tower to Harrah's Casino 제주 출장마사지 And 제천 출장마사지 Earth Tower costs 익산 출장안마 only $2, and the quickest way takes just 1 hour.