TokyoTyrantをモデルっぽく使う TokyoTyrantStorage
Python
2011-06-09 08:37 (15 years ago)

# -*- coding: utf-8 -*-
"""
TokyoTyrantをモデルっぽく使う
class Soldier(TokyoTyrantStorage):
hp = TokyoTyrantStorage.Field(default=0)
mp = TokyoTyrantStorage.Field(default=0)
cain = Soldier('Cain')
cain.hp = 100
cain.mp = 50
cain.save()
abel = Soldier('Abel')
abel.hp = 50
abel.mp = 100
abel.save()
cain = Soldier('Cain')
cain.hp -= 80
cain.save()
abel = Soldier('Abel')
abel.mp -= 20
abel.save()
cain = Soldier('Cain')
cain.hp = min(cain.hp + 50, 100)
cain.save()
cain = Soldier('Cain')
cain.hp
Out: 70
"""
import logging
from tokyotyrant import get_client
import msgpack
class TokyoTyrantStorage(object):
"""
TokyoTyrantをディクショナリとして使う基底クラス
継承して使ってください
"""
packer = msgpack.Packer()
tt_client = get_client()
def __new__(cls, *args, **kwargs):
for k, v in vars(cls).iteritems():
if isinstance(v, TokyoTyrantStorage.Field):
v.set_field_name(k)
return object.__new__(cls)
def __init__(self, key_object):
"""
@param key_object djangoのモデルインスタンスなど。player や osuser
オーバーライドして、superの__init__を呼びたくないときは
そのまま self.after_init(key_part) する
"""
self.key_object = key_object
key_part = getattr(key_object, 'pk', str(key_object))
self.after_init(key_part)
def after_init(self, key_part):
"""
初期化処理の後半
@param (str)key_part キー生成の元となるユニークな文字列
"""
self.kvs_key = '%s::%s' % (self.__class__.__name__, key_part)
bulk_storage = self.tt_client.get(self.kvs_key, None)
if bulk_storage:
self.storage = msgpack.unpackb(bulk_storage)
else:
self.storage = {}
def get(self, k, default=None):
return self.storage.get(k,default)
def set(self, k, value):
self.storage[k] = value
def save(self):
"""
storageを保存
"""
self.tt_client.set(self.kvs_key, self.packer.pack(self.storage))
def delete(self):
"""
storageを削除
"""
self.tt_client.out(self.kvs_key)
self.storage = {}
def dump(self):
logging.debug("[TokyoTyrantStorage] dump: kvs_key=%s, storage=%r" % (self.kvs_key, self.storage))
class Field(object):
"""
TokyoTyrantStorage に使えるフィールド
score = TokyoTyrantStorage.Field(default=0) みたいに使う。
"""
def __init__(self, key_name=None, default=None):
self._key_name = key_name
self.default = default
def __get__(self, inst, type=None):
assert isinstance(inst, TokyoTyrantStorage), '%s use only TokyoTyrantStorage class.' % self.__class__.__name__
return inst.get(self.key_name, self.default)
def __set__(self, inst, value):
assert isinstance(inst, TokyoTyrantStorage), '%s use only TokyoTyrantStorage class.' % self.__class__.__name__
inst.set(self.key_name, value)
def set_field_name(self, field_name):
#TokyoTyrantStorage.__new__ から呼ばれる
self.field_name = field_name
@property
def key_name(self):
return self._key_name or self.field_name
評価をお願いします (会員登録・ログイン不要)
まだ評価がありません
著者は、アプリケーション開発会社 Cyberneura を運営しています。
開発相談をお待ちしています。
開発相談をお待ちしています。