When designing applications or libraries, sometimes you need to be able to create instances of a certain interface (in a liberal sense) at runtime without knowing at write/compile time which specific implementation (class) you’ll need to use, as this could depend on runtime variables.
An example of this is an interface providing some functionality which should be implemented differently on different platforms, eg Linux and Windows.
There are some standard patterns how to achieve this. One of them is the factory pattern, which works somewhat like this Python example (let’s pretend ‘PLATFORM’ is ‘linux2′ or ‘win32′, ie sys.platform):
#Pretend we use sys.platform instead of PLATFORM where we use it
PLATFORM = 'linux2'
class FooBase(object):
def say_foo(self):
print 'foo'
class PlatformFoo(FooBase):
def say_platform_foo(self):
raise NotImplementedError
@staticmethod
def get_class():
#Several ways to get this (dict, introspection, if-tree,...), pick yours
klass = {
'linux2': LinuxFoo,
'win32': WindowsFoo,
}.get(PLATFORM, None)
if not klass:
raise Exception, 'Platform not supported'
return klass
class WindowsFoo(PlatformFoo):
def say_platform_foo(self):
print 'win32 foo'
class LinuxFoo(PlatformFoo):
def say_platform_foo(self):
print 'linux foo'
def main():
foo_class = PlatformFoo.get_class()
foo = foo_class()
foo.say_platform_foo()
if __name__ == '__main__':
main()
Executing this code will, as expected, write ‘linux foo’ to the console. Obviously we could not return the platform-specific class in a PlatformFoo function, but an actual instance, up to you.
Python allows you to handle this situation somewhat nicer though, without introducing any intermediate functions, by using metaclasses.













