OOREDIS:一个Pythonic的Redis库。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
huangz
V2EX    Redis

OOREDIS:一个Pythonic的Redis库。

  •  
  •   huangz
    huangzworks 2011-08-06 19:51:25 +08:00 9205 次点击
    这是一个创建于 5226 天前的主题,其中的信息可能已经有所发展或是发生改变。
    用Redis的朋友们应该会发现,Redis的很多客户端都只是Redis命令的一个简单包装。

    举个例子,在Redis的Python客户端redis-py中,设置一个String键的方法如下:

    >>> from redis import Redis
    >>> r = Redis
    >>> r.set('key_name', 'value')

    而要取得一个列表的所有元素,则要使用lrange命令:

    >>> r.lrange('list', 0, -1)

    这种操作方式有几个问题:

    1.大量的Redis命令聚在一起,妨碍了对客户端对象的使用。

    2.每次操作都要将将key name和命令参数(比如lrange的0和-1)显式地传入方法当中,容易出错。

    3.命令之间没有限制,可以互相覆盖而没有错误提示。

    比如你可以用set命令覆盖一个Redis列表,Redis本身不会报错。

    4.客户端没有利用到语言提供的方便机制。

    比如r.lrange('list', 0, -1)在Python中就没有for item in list语句来得直观。

    5.Redis只储存字符串值,虽然可以储存整数或浮点数,但每次取出值都要显式类型转换,很不方便。

    ---

    为了解决以上问题,更好地使用Redis,我用Python写了一个Redis库,基于redis-py,名叫ooredis。

    ooredis有以下目标:

    1.以Key对象为单位操作Redis的数据结构

    在ooredis中,Redis的函数被按类型及作用归为了一个个Python类,每个ooredis类有不同的操作。

    比如在ooredis中,将Redis的Hash类函数包裹成了Dict类型,它可以以类似Python内置dict类型的方式,操纵Redis数据。

    又比如,Redis的List类函数,在ooredis中被包裹成了List类型,它可以以类似Python内置list类型的方式,操纵Redis数据。

    如果ooredis类尝试覆盖不同类型的数据,ooredis将抛出异常。

    这样就解决了包括命名空间污染、跨类型覆盖等问题。

    2.提供一组Pythonic的API

    刚才我们说“以类型Python内置的dict类型的方式来操纵Redis的Hash类型数据“,我们还没详细说明这是什么意思。

    比如说,在ooredis中,你可以通过传给Dict类一个key name,之后就可以操纵这个Dict对象,来完成Redis中的各种命令,像这样:

    >>> form ooredis import *
    >>> project = Dict('ooredis-project')
    >>> project['name'] = 'ooredis'
    >>> project['version'] = 1.0
    >>> project['author'] = 'huangz'

    以上的语句就相当于执行Redis的命令:

    redis> HSET ooredis name ooredis
    redis> HSET ooredis version 1.0
    redis> HSET ooredis author huangz

    也可以用redis-py来完成上面的任务:

    >>> r.hset('ooredis-project', 'name', 'ooredis')
    >>> r.hset('ooredis-project', 'version', 1.0)
    >>> r.hset('ooredis-project', 'autohr', 'huangz)

    可以看到,使用Dict对象比单纯的Redis命令更直观。

    又比如在Dict对象中,你可以用Python内置类型set的全部命令:items、keys、values、pop,等等。

    >>> project.items()
    [('name', u'ooredis'), ('version', 1.0), ('author', u'huangz')]
    >>> 'version' in project
    True
    >>> project.pop('name')
    u'ooredis'

    不仅是Dict类,ooredis的所有类都大量使用了Python的魔法方法,致力于让Redis数据的操作更直观、清晰和Pythonic。

    3.提供方便的类型转换机制

    至于类型问题,ooredis通过使用传入TypeCase的方式,来对Redis数据进行类型转换。

    比如如果你需要一个只保存整数对象(int/long)类型的列表,只需要这样做就可:

    >>> numbers = List('numbers', type_case=IntTypeCase)

    如果你需要一个只接受Json对象的字典对象,只需要使用以下语句:

    >>> json_only_dict = Dict('json_dict', type_case=JsonTypeCase)

    其中IntTypeCase和JsonTypeCase都是ooredis默认提供的TypeCase类之一,ooredis总共提供了以下常用TypeCase:

    GenericTypeCase,接受Python常量值,比如int,long,float,str和unicode。为了世界的和平与正义,传入的字符串值总被转换成unicode类型。

    IntTypeCase,接受int和long。

    FloatTypeCase,接受浮点数。

    StringTypeCase,接受str和unicode类型的值,而且总被转换成unicode。

    JsonTypeCase,接受所有可被转换成Json对象的值,比如Python的dict类型。

    SerializeTypeCase,使用Pickle的dumps和loads,可以对Python的class进行序列化。

    当然,除了以上的TypeCase之外,你也可以很方便地定义自己的TypeCase类,像如下代码:

    class MyTypeCase:
    @staticmethod
    def to_redis(value):
    pass
    @staticmethod
    def to_python(value):
    pass

    to_redis将值转换成Redis能接受的类型,to_python则将从Redis取出的数据转回原来的类型。

    ---

    好的,以上就是关于ooredis的基本介绍了,抱歉因为时间关系我不能写一篇更短的文章。

    如果你对ooredis有兴趣,可以访问以下地址,获得更多信息:

    ooredis的更详细介绍,幻灯: http://bit.ly/rbgn3Z

    ooredis的项目主页: https://github.com/huangz1990/ooredis

    最后,祝情侣们七夕快乐,早生贵子。

    XD
    2 条回复    1970-01-01 08:00:00 +08:00
    ayanamist
        1
    ayanamist  
       2011-08-06 21:34:03 +08:00
    嗯,先赞楼主一个~希望能一直维护下去。目前开源项目最大的问题就是缺乏长久的支持啊……
    huangz
        2
    huangz  
    OP
       2011-08-07 08:31:06 +08:00
    @ayanamist 是阿是阿,打一枪就跑的开源项目的确挺讨厌的,我会尽量抽时间维护的。现阶段的目标是打算丰富一下文档,争取让更多人来使用和维护,这样我的工作量也能少一些。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     913 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 22:00 PVG 06:00 LAX 14:00 JFK 17:00
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86