Dependency Injection in Python
At the moment I am writing a simple IRC service bot for our Open4Free IRC network, during development I remembered a pattern called Dependency Injection, also known as Inversion of Control (IoC). While this Pattern is spread in Java World, the Python community has very few references to this topic.
The reason why I want to use Inversion of Control in my Bot is to provide an extensible architecture that shall be able to access and define shared services. Well the Python version of this pattern is extremely simple, since Python is highly flexible.
import inspect class Inject(object): def __init__(self, interface): self.interface = interface class Container(object): def __init__(self): self.implementations = {} self.instances = {} def addComponent(self, interface, implementation=None): self.implementations[interface] = implementation or interface def getComponent(self, interface): if interface in self.instances: return self.instances[interface] if interface not in self.implementations: return None cls = self.implementations[interface] instance = self.instances[interface] = cls.__new__(cls) for key, classvalue in inspect.getmembers(cls): if isinstance(classvalue, Inject): value = self.getComponent(classvalue.interface) setattr(instance, key, value) instance.__init__() return instance
With this code you can register any new-style class and inject other instances into it by adding an instance of Inject into the class values.
class A(object): def test(self): print "A.test()" class B(object): a = Inject(A) def test(self): self.a.test() print "B.test()", self test = Container() test.addComponent(A) test.addComponent(B) test.getComponent(B).test()
And of course you use interfaces to make components replaceable, or just replace the implementation of some components by other implementations.
class A(object): def test(self): print "A.test()" class B(object): a = Inject(A) def test(self): self.a.test() print "B.test()", self class ImprovedA(A): def test(self): print "ImprovedA.test()" test = Container() test.addComponent(A, ImprovedA) test.addComponent(B) test.getComponent(B).test()
by Dennis at10:53 PM under dependency injection, inversion of control, python (Comments)




