Saturday, May 2, 2009

Python: alternative class initializers

You may notice that some Python modules have classes that define more than one initializer. Why you may want this is if you have more than one input method of initializing it. For example, you can have an RPC class (just an example) which can take both XML and JSON arguments when initializing. There are more than one way of doing this, but having a couple of initializers is the most beautiful way, in my opinion. Basically, we're going to have two methods on the class: from_json and from_xml. These will be @classmethods. From what I understand (I'm still quite new at Python), classmethods are somewhere between instance methods and static functions. The main difference between a class method and an instance method is the fact that the class method receives, as a first argument, the class itself, not an instance of it. Static methods don't receive a special first argument at all. Okay! Let's get to the code: class MyClass: @classmethod def from_json(cls, json_string): obj = cls() obj.created_from = 'json' # Do stuff, parse json_string, set attributes on obj, etc return obj @classmethod def from_xml(cls, xml_string): obj = cls() obj.created_from = 'xml' # Do stuff, parse xml_string, set attributes on obj, etc return obj def get_create_method(self): return self.created_from We have our two initializers. Here's some example usage: instance_one = MyClass.from_json(json_string) print instance_one.get_create_method() # 'json' instance_two = MyClass.from_xml(xml_string) print instance_two.get_create_method() # 'xml' Sure, classmethods aren't used solely for multiple initializers, but it's one of the most useful things you can do with them.