返回介绍

16.2 Python 和 Redis

发布于 2024-01-26 22:39:51 字数 9638 浏览 0 评论 0 收藏 0

了解完Redis的基础知识后,我们最关心的是如何使用Python对Redis进行操作。Redis有很多开源的Python接口,但是比较成熟和稳定的,也是我比较推荐的是redis-py,如图16-7所示。

图16-7 Python接口

16.2.1 Python操作Redis

1.安装Redis

·pip install redis

·从https://github.com/andymccurdy/redis-py 下载源码,执行python setup install。

2.建立连接

首先导入redis模块,通过指定主机和端口和redis建立连接,进行操作,示例如下:

  import redis
  r = redis.Redis(host='127.0.0.1', port=6379)
  r.set('name', 'qiye')
  print r.get('name')

或者使用连接池管理redis的连接,避免每次建立、释放连接的开销,示例如下:

  pool = redis.ConnectionPool(host='127.0.0.1', port=6379)
  r = redis.Redis(connection_pool=pool)
  r.set('name', 'qiye')
  print r.get('name')

3.操作string类型

下面讲解一下常用的操作string类型的方法。

1)set(name,value,ex=None,px=None,nx=False,xx=False)

说明:用于设置键值对。

参数:

·name:键。

·value:值。

·ex:过期时间,单位秒。

·px:过期时间,单位毫秒。

·nx:如果设置为True,则只有name不存在时,当前set操作才执行。

·xx:如果设置为True,则只有name存在时,当前set操作才执行。

示例如下:

  import redis
  pool = redis.ConnectionPool(host='127.0.0.1', port=6379)
  r = redis.Redis(connection_pool=pool)
  r.set('name', 'qiye',ex=3)
  print r.get('name')

3秒之后name键所对应的值为None。

2)setnx(name,value)

说明:只有当name不存在时,才能进行设置操作。

参数:

·name:键。

·value:值。

示例如下:

r.setnx('name','hah')

3)setex(name,value,time)

说明:用于设置键值对。

参数:

·name:键。

·value:值。

·time:过期时间,可以是timedelta对象或者是数字秒。

示例如下:

r.setex("name","qiye",5)
print r.get('name')

5秒后,name的值变为None。

4)psetex(name,time_ms,value)

说明:用于设置键值对。

参数:

·name:键。

·time_ms:过期时间,可以是timedelta对象或者是数字毫秒。

·value:值。

示例如下:

r. psetex ("name",5000,"qiye")
print r.get('name')

5秒后,name的值变为None。

5)mset(*args,**kwargs)

说明:用于批量设置键值对。

示例如下:

r.mset(age=20,country='china')

6)mget(keys,*args)

说明:用于批量获取键值。

参数:

·keys:多个键。

示例如下:

print r.mget('age','country')
print r.mget(['age','country'])

7)getset(name,value)

说明:用于设置新值并获取原来的值。

参数:

·name:键。

·value:值。

示例如下:

print r.getset('name','hello')

打印出来的值为qiye,也就是之前设置的值。

8)getrange(key,start,end)

说明:根据字节获取子字符串。

参数:

·key:键。

·start:起始位置,单位字节。

·end:结束位置,单位字节。

示例如下:

  r.set('name','qiye安全博客')
  print r.getrange('name',4,9)

输出结果为:安全,因为汉字是3个字节,字母是1个字节。

9)setrange(name,offset,value)

说明:从指定字符串索引开始向后修改字符串内容。

参数:

·name:键。

·offset:索引,单位字节。

·value:值。

示例如下:

  r.set('name','qiye安全博客')
  r.setrange("name",1,"python")
  print r.get('name')

输出结果为:qpython全博客。

10)setbit(name,offset,value)

说明:对name对应值的二进制形式进行位操作。

参数:

·name:键。

·offset:索引,单位为位。

·value:0或1。

示例如下:

  from binascii import hexlify
  r.set('name','qiye')
  print bin(int(hexlify('qiye'),16))
  r.setbit('name',2,0)
  print r.get('name')
  print bin(int(hexlify(r.get('name')),16))

输出结果为:

  01110001011010010111100101100101
  Qiye
  01010001011010010111100101100101

11)getbit(name,offset)

说明:获取name对应值的二进制形式中某位的值。

参数:

·name:键。

·offset:索引,单位为位。

示例如下:

print r.getbit('name',2)

12)bitcount(key,start=None,end=None)

说明:获取name对应值的二进制形式中1的个数。

参数:

·key:Redis的name。

·start:字节起始位置。

·end:字节结束位置。

示例如下:

print r.bitcount('name',0,1)

13)strlen(name)

说明:返回name对应值的长度。

参数:

·name:键。

示例如下:

print r.strlen('name')

14)append(key,value)

说明:在name对应值之后追加内容。

参数:

·key:键。

·value:要追加的字符串。

示例如下:

r.append('name','python')

4.操作hash类型

下面讲解一下常用的操作hash类型的方法。

1)hset(name,key,value)

说明:设置name对应hash中的一个键值对,如果不存在,则创建;否则,进行修改。

参数:

·name:hash的name。

·key:hash中的key。

·value:hash中的value。

示例如下:

r.hset('student','name','qiye')

2)hmset(name,mapping)

说明:在name对应的hash中批量设置键值对。

参数:

·name:hash的name。

·mapping:字典。

示例如下:

r.hmset('student', {'name':'qiye', 'age': 20})

3)hget(name,key)

说明:获取name对应的hash中key的值。

参数:

·name:hash的name。

·key:

示例如下:

r.hget('student','name')

4)hmget(name,keys,*args)

说明:批量获取name对应的hash中多个key的值。

参数:

·name:hash对应的name。

·keys:要获取的key集合,如:['k1','k2','k3']。

·*args:要获取的key,如:k1,k2,k3。

示例如下:

print r.hmget('student',['name','age'])
print r.hmget('student','name','age')

5.操作list类型

下面讲解一下常用的操作list类型的方法。

1)lpush(name,values)

说明:在name对应的list中添加元素,每个新的元素都添加到列表的最左边。

参数:

·name:list对应的name。

·values:要添加的元素。

示例如下:

r.lpush('digit', 11,22,33)

存储顺序为:33,22,11。添加到list右边使用rpush(name,values)方法。

2)linsert(name,where,refvalue,value)

说明:name对应的列表的某一个值前或后插入一个新值。

参数:

·name:list的name。

·where:before或after。

·refvalue:在它前后插入数据。

·value:插入的数据。

示例如下:

r.linsert("digit","before","22","aa")

这个例子的意思是往列表中左边第一个出现的元素22前插入元素aa。

3)r.lset(name,index,value)

说明:对name对应list中的某一个索引位置赋值。

参数:

·name:list的name。

·index:list的索引位置。

·value:要设置的值。

示例如下:

r.lset("digit",4,44)

4)lrem(name,value,num)

说明:在name对应的list中删除指定的值。

参数:

·name:list的name。

·value:要删除的值。

·num:第num次出现。当num=0,删除列表中所有的指定值。

示例如下:

r.lrem("digit","22",1)

5)lpop(name)

说明:在name对应列表的左侧获取第一个元素并在列表中移除和返回。

参数:

·name:list的name。

示例如下:

r.lpop("digit")

6.操作set类型

下面讲解一下常用的操作set类型的方法。

1)sadd(name,values)

说明:为name集合添加元素。

参数:

·name:set的name。

·values:要添加的元素。

示例如下:

r.sadd("num",33,44,55,66)

2)scard(name)

说明:获取name对应的集合中元素的个数。

参数:

·name:set的name。

示例如下:

r.scard(name)

3)smembers(name)

说明:获取name对应的集合的所有成员。

参数:

·name:set的name。

示例如下:

r. smembers (name)

4)sdiff(keys,*args)

说明:获取多个name对应集合的差集。

示例如下:

print(r.sdiff("num1 ","num2"))

含义是求num1和num2的差集。

5)sinter(keys,*args)

说明:获取多个name对应集合的交集。

示例如下:

print(r. sinter ("num1 ","num2"))

含义是求num1和num2的交集。

6)sunion(keys,*args)

说明:获取多个name对应集合的并集。

示例如下:

print(r. sunion ("num1 ","num2"))

含义是求num1和num2的并集。

7.操作sorted set类型

下面讲解一下常用的操作sorted set类型的方法。

1)zadd(name,*args,**kwargs)

说明:在name对应的有序集合中添加元素和元素对应的分数。

示例如下:

r.zadd("z_num",num1=11,num2=22)

2)zcard(name)

说明:获取name对应的有序集合中元素个数。

示例如下:

print r. zcard ("z_num")

3)zrange(name,start,end,desc=False,withscores=False,score_cast_func=float)

说明:按照索引范围获取name对应的有序集合的元素。

参数:

·name:sorted set的name。

·start:有序集合索引起始位置(非分数)。

·end:有序集合索引结束位置(非分数)。

·desc:排序规则,默认按照分数从小到大排序。

·withscores:是否获取元素的分数,默认只获取元素的值。

·score_cast_func:对分数进行数据转换的函数。

示例如下:

print r. zrange ("z_num",0,10)

4)zrem(name,values)

说明:删除name对应有序集合中值是values的成员。

示例如下:

zrem(' z_num ', ['num1', 'num2'])

5)zscore(name,value)

说明:获取name对应有序集合中value对应的分数。

示例如下:

print(r.zscore("z_num","num1"))

16.2.2 Scrapy集成Redis

在Scrapy中,如果想实现分布式,需要使用Redis作为消息队列,通过安装scrapy-redis组件就可以实现。scrapy-redis在Scrapy框架的哪一部分起作用呢?可以在使用前和使用后进行一下对比。原框架工作流程如图16-8所示。

图16-8 Request队列

使用scrapy-redis后的架构,如图16-9所示。

前后发生的主要变化是Request队列放到了Redis中,这样多个单机就可以通过Redis获取Request,实现分布式,同时将要存储的结构化数据存到Redis队列中。

图16-9 Redis Request队列

下面安装scrapy-redis,官方文档:https://scrapy-redis.readthedocs.org ,主要有两种安装方式:

·pip install scrapy_redis

·从https://github.com/rolando/scrapy-redis 下载源码,解压后,使用Python setup.py install命令。

安装完成后,需要在settings中进行配置才能使用,配置字段如下:

  # 使用scrapy_redis的调度器:
  SCHEDULER = "scrapy_redis.scheduler.Scheduler"
  # 在Redis中保持scrapy-redis用到的各个队列,从而允许暂停和暂停后恢复:
  SCHEDULER_PERSIST = True
  # 使用scrapy_redis的去重方式:
  DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
  # 使用scrapy_redis的存储方式:
  ITEM_PIPELINES = {
     'scrapy_redis.pipelines.RedisPipeline': 300
  }
  # 定义Redis的IP和端口:
  REDIS_HOST = '127.0.0.1'
  REDIS_PORT = 6379

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文