[an error occurred while processing this directive]
[an error occurred while processing this directive]
シリアライズ
新スタイルクラスでやりたい放題。
Pythonのクラスには、
class A:
...
と書き始める「古い」スタイルのクラスと、
class A(object):
....
と書き始める「新しい」スタイルのクラスがあります。
下のスタイルで追加された変数を用いると、色々と面白いことができます。
まずは__class__。このオブジェクトがどのクラスのインスタンスか知りたければ、
a = A()
b = A()
if a.__class__ == b.__class__:
print "Onaji!"
else :
print "Chigau!"
みたいに使えます。JavaだとinstanceOfってのがありますね。
さらにこわいことに、この__class__に代入することによって、動的にどのクラスのインスタンスか変えることができます。こわいこわい…
あと、メンバ変数に値を追加したいけど、その変数の名前が変数に入ってる…
というとき、C++やJavaだとswitchで変数ごとの振り分けを書かなければいけません。
でも、pythonの__dict__を使うと一発です。
class A(object):
def __init__(self):
self.temperature = 20
a = A()
a.__dict__["weather"] = "fine"
print a.weather
いつの間にかaにweatherという変数が追加されています。こわいこわい。
シリアライズのサンプル (新)
シリアライズのサンプルを作ってみました。適当なクラスをmyObjectを継承して書くと、
save()とload()が使えるようになるはずです。(セキュリティ的にはだめだめです)
class myObject(object):
def load(self, fn):
fd = open(fn, "r")
lines = fd.readlines()
cursor = 0
while cursor < len(lines):
key = eval(lines[cursor])
value = eval(lines[cursor+1])
self.__dict__[key] = value
cursor += 2
fd.close()
def save(self, fn):
fd = open(fn, "w")
for key,value in self.__dict__.items():
print >> fd, repr(key)
print >> fd, repr(value)
fd.close()
こんなふうにつかう。
class A(myObject):
def __init__(self, fn = None):
if fn is None:
self.A = {"a":123, "b":234, "c":345}
self.B = "ancde"
else:
self.load(fn)
a = A()
a.save("x")
ax = A("x")
print ax.A, ax.B
シリアライズのサンプル (旧)
ちょっと古いやつ。上のが高機能。
シリアライズのサンプルを作ってみました。文字列型のメンバ変数しかサポートしていません。
[変数名の長さ][変数名][値の長さ][値]というバイト列に変換します。
import struct
class A(object):
def __init__(self, **args):
if "fromHost" in args:
self.fromHost = args["fromHost"]
self.toHost = args["toHost"]
self.filename = args["filename"]
elif "str_expr" in args:
self.deserialize(args["str_expr"])
else :
raise "Unsupported way to construct"
def deserialize(self, msg):
tip = struct.calcsize('l')
cnt = 0
while len(msg) > cnt :
keylen = struct.unpack('l', msg[cnt:(cnt+tip)])[0]
cnt += tip
key = msg[cnt:(cnt + keylen)]
cnt += keylen
valuelen = struct.unpack('l', msg[cnt:(cnt+tip)])[0]
cnt += tip
value = msg[cnt:(cnt + valuelen)]
cnt += valuelen
self.__dict__[key] = value
def serialize(self) :
ret = ""
for key in ["fromHost", "toHost", "filename"]:
value = self.__dict__[key]
ret += struct.pack('l', len(key)) + key
ret += struct.pack('l', len(value)) + value
return ret
def write(self) :
for key in self.__dict__:
value = self.__dict__[key]
print " %s = %s"%(key, value)
a = A(fromHost = "192.169.0.1", toHost = "192.168.0.2", filename = "hoge.c")
msg = a.serialize()
b = A(str_expr = msg)
b.write()
[an error occurred while processing this directive]