個別のReader/Writerクラスを作成する目的は、コンソールへの書き込み、バイトへの書き込み、JSON文字列への書き込みなど、さまざまな出力処理をサポートすることです。重要なことは、Struct1、Struct2などの各クラスが、状態を保存するために重要な属性を認識していることです。これは、ピクルスモジュールで使用される哲学です。
class Struct1(object):
fields = ('a','b','c')
...
class Struct2(object):
fields = ('foo', 'bar', 'baz')
...
これで、クラス固有のコードを記述しなくても、このメタデータを使用してさまざまなライタークラスを記述できます。
class StructWriter(object):
packTypeMap = {int:'i', float:'f', str:'s'}
def write(self, obj):
fields = obj.fields
packstring = ''.join(packTypeMap[type(f)] for f in fields)
packargs = (getattr(obj,f) for f in fields)
return struct.pack(packstring, *packargs)
class DictWriter(object):
def write(self, obj):
return dict((f, getattr(obj,f)) for f in obj.fields)
class JSONWriter(object):
jsonTypeMap = {str:lambda s:"'"+s+"'"}
defaultJsonFunc = lambda x:str(x)
def write(self, obj):
# not really recommended to roll your own strings, but for illustration...
fields = obj.fields
outargs = (getattr(obj,f) for f in fields)
outvals = (jsonTypeMap.get(type(arg),defaultJsonFunc)(arg)
for arg in outargs)
return ('{' +
','.join("'%s':%s" % field_val for field_val in zip(fields, outvals))
'}')
class ZipJSONWriter(JSONWriter):
def write(self, obj):
import zlib
return zlib.compress(super(ZipJSONWriter,self).write(obj))
class HTMLTableWriter(object):
def write(self, obj):
out = "<table>"
for field in obj.fields:
out += "<tr><td>%s</td><td>%s</td></tr>" % (field, getattr(obj,field))
out += "</table>"
return out