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

OOREDIS:一个Pythonic的Redis库。

  •  
  •   huangz ·
    huangz1990 · 2011-08-06 19:51:25 +08:00 · 8309 次点击
    这是一个创建于 4618 天前的主题,其中的信息可能已经有所发展或是发生改变。
    用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   ·   我们的愿景   ·   实用小工具   ·   1700 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 16:43 · PVG 00:43 · LAX 09:43 · JFK 12:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.