Python redis操作

这篇博客详细介绍了如何在Python中操作Redis,包括安装、基本连接、连接池的使用,以及Hash、List、Set等数据结构的操作,如设置、获取、修改、删除等。还提到了增量迭代和集合操作中的差集、交集、并集等高级用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

安装

ubuntu下安装

sudo apt-get install redis

基本操作

连接方式:

  • 严格连接模式:r=redis.StrictRedis(host=”“,port=)
  • 更Python化的连接模式:r=redis.Redis(host=”“,port=)
  • StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令
  • Redis与StrictRedis的区别是:Redis是StrictRedis的子类,用于向前兼容旧版本的redis-py,并且这个连接方式是更加”python化”的
  • 连接池
    为了节省资源,减少多次连接损耗,连接池的作用相当于总揽多个客户端与服务端的连接,当新客户端需要连接时,只需要到连接池获取一个连接即可,实际上只是一个连接共享给多个客户端。

如下我们使用连接池方式连接redis:

import redis
pool = redis.ConnectionPool(host='localhost', port=6379, db=0, decode_responses=True)
r = redis.Redis(connection_pool=pool)
r.set('a','3')
print(r.get('a'))
3

默认情况下,设置的值或取得的值都为bytes类型,如果想改为str类型,需要在连接时添加上decode_responses=True

增加

在Redis中设置值,默认不存在则创建,存在则修改

r.set(‘name’, ‘zhangsan’)

参数:
     set(name, value, ex=None, px=None, nx=False, xx=False)  
     ex,过期时间(秒)  
     px,过期时间(毫秒)  
     nx,如果设置为True,则只有name不存在时,当前set操作才执行,同setnx(name, value)  
     xx,如果设置为True,则只有name存在时,当前set操作才执行 
# 批量设置
r.mset(a1='1',a2='2')
#r.mset({'a1':'1','a2':'2'})

# 批量获取  r.mget()
print(r.mget('a1','a2'))
['1', '2']

查找获取

r.get('key_name')

#根据字节获取子序列
r.set("name","zhangsan")
print(r.getrange("name",0,3))
zhan

修改

#修改字符串内容,从指定字符串索引开始向后替换,如果新值太长时,则向后添加
r.set("name","zhangsan")
r.setrange("name",1,"z")
print(r.get("name")) 
r.setrange("name",6,"zzzzzzz")
print(r.get("name"))
zzangsan
zzangszzzzzzz

删除

delete(*names)
根据删除redis中的任意数据类型(string、hash、listset、有序set
r.delete("gender")  # 删除key为gender的键值对
1

获取长度

#返回name对应值的字节长度(一个汉字3个字节)
r.set("name","zhangsan")
print(r.strlen("name"))
8

检查名字是否存在

exists(name)
检测redis的name是否存在,存在就是TrueFalse 不存在

hash操作

redis中的Hash 在内存中类似于一个name对应一个dic来存储

新增/修改

hset(‘dic_name’,’key’,’value’)

如果存在该dic,则增加(key,value), 不存在则创建,如果key在dic里面是存在的,就修改该key的值

#name对应的hash中设置一个键值对(不存在,则创建,否则,修改)
r.hset("dic_name","a1","aa")

print(r.hget("dic_name","a1"))
aa

查找获取

#在name对应的hash中批量设置键值对,mapping:字典
dic={"a1":"aa","b1":"bb"}
r.hmset("dic_name",dic)

# 获取指定dic,指定key的value
print(r.hget("dic_name","b1"))#输出:bb

# 获取dic全部的键值对
print(r.hgetall("dic_name"))

# 在name对应的hash中获取多个key的值
li=["a1","b1"]
print(r.hmget("dic_name",li))
print(r.hmget("dic_name","a1","b1"))


#hlen(name) 获取hash中键值对的个数
print(r.hlen("dic_name"))

#hkeys(name) 获取hash中所有的key的值
print(r.hkeys("dic_name"))

#hvals(name) 获取hash中所有的value的值
print(r.hvals("dic_name"))
#检查name对应的hash是否存在当前传入的key
print(r.hexists("dic_name","a1"))#输出:True

删除

#删除指定name对应的key所在的键值对
r.hdel("dic_name","a1")
print(r.hgetall('dic_name'))

r.hset('dic_name','a1','aa')
print(r.hgetall('dic_name'))

List操作

redis中的List在在内存中按照一个name对应一个List来存储

# 在name对应的list中添加元素,每个新的元素都添加到列表的最左边,没有该list则新建
r.lpush("list_name",2)
r.lpush("list_name",3,4,5)#保存在列表中的顺序为5,4,3,2

r.lpushx('list_name',6)  #在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边

r.rpushx('list_name',7)  #在name对应的list中添加元素,只有name已经存在时,值添加到列表的最右边

#rpush(name,values) 个新的元素都添加到列表的最右边

print(r.lrange('list_name',0,-1)) #分片获取元素
print(r.llen("list_name"))  # 获取list的长度
['6', '5', '4', '3', '2', '7']
6

在name对应的列表的某一个值前或后插入一个新值

r.linsert("list_name","BEFORE","2","SS") #在列表内找到第一个元素2,在它前面插入SS
参数:
     name: redis的name
     where: BEFORE(前)或AFTER(后)
     refvalue: 列表内的值
     value: 要插入的数据
r.linsert('list_name','BEFORE','2','ss')
print(r.lrange('list_name',0,-1))


r.lset('list_name', 0, 'test')
print(r.lrange('list_name',0,-1))
['6', '5', '4', '3', 'ss', '2', '7']
['test', '5', '4', '3', 'ss', '2', '7']

删除(指定值进行删除,返回值)

#移除列表的左侧第一个元素,返回值则是第一个元素
print(r.lpop("list_name"))
print(r.lrange('list_name',0,-1))
test
['5', '4', '3', 'ss', '2', '7']

删除(指定值进行删除,删除不返回)

r.lrem(name, value, num)  

在name对应的list中删除指定的值  

参数:
name,redis的name
value,要删除的值
numnum=0,删除列表中所有的指定值;
num=2,从前到后,删除2个; num=1,从前到后,删除左边第1num=-2,从后向前,删除2

删除索引之外的值

ltrim(name, start, end)

在name对应的列表中移除没有在start-end索引之间的值
参数:
name,redis的name
start,索引的起始位置
end,索引结束位置

取值(根据索引号取值)

lindex(name, index)
在name对应的列表中根据索引获取列表元素

移动 从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边

rpoplpush(src, dst)

参数:
src,要取数据的列表的name
dst,要添加数据的列表的name

移动 元素从一个列表移动到另外一个列表 可以设置超时

brpoplpush(src, dst, timeout=0)
从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧
参数:
src,取出并要移除元素的列表对应的name
dst,要插入元素的列表对应的name
timeout,当src对应的列表中没有数据时,阻塞等待其有数据的超时时间(秒),0 表示永远阻塞

一次移除多个列表

blpop(keys, timeout)
将多个列表排列,按照从左到右去pop对应列表的元素
参数:
keys,redis的name的集合
timeout,超时时间,当元素所有列表的元素获取完之后,阻塞等待列表内有数据的时间(秒), 0 表示永远阻塞
更多:
r.brpop(keys, timeout) 同blpop,将多个列表排列,按照从右像左去移除各个列表内的元素

r.lpush("list10", 3, 4, 5)
r.lpush("list11", 3, 4, 5)

while r.llen('list11') > 0:
    r.blpop(["list10", "list11"], timeout=2)
    print(r.lrange("list10", 0, -1), r.lrange("list11", 0, -1))
['4', '3'] ['5', '4', '3']
['3'] ['5', '4', '3']
[] ['5', '4', '3']
[] ['4', '3']
[] ['3']
[] []

自定义增量迭代

由于redis类库中没有提供对列表元素的增量迭代,如果想要循环name对应的列表的所有元素,那么就需要:

  • 获取name对应的所有列表
  • 循环列表

但是,如果列表非常大,那么就有可能在第一步时就将程序的内容撑爆,所有有必要自定义一个增量迭代的功能:

def list_iter(name):
    """
    自定义redis列表增量迭代
    :param name: redis中的name,即:迭代name对应的列表
    :return: yield 返回 列表元素
    """
    list_count = r.llen(name)
    for index in range(list_count):
        yield r.lindex(name, index)

# 使用
for item in list_iter('list2'): # 遍历这个列表
    print(item)

Set操作

Set集合就是不允许重复的列表

  • 新增
    sadd(name,values)
    name对应的集合中添加元素
  • scard(name) 获取元素个数 类似于len
  • 获取集合中所有的成员
    • smembers(name) 获取集合中所有的成员
    • sscan(name, cursor=0, match=None, count=None) 获取集合中所有的成员–元组形式
    • sscan_iter(name, match=None, count=None) 获取集合中所有的成员–迭代器的方式
  • 移动
    smove(src, dst, value)
    将某个成员从一个集合中移动到另外一个集合
  • 删除–随机删除并且返回被删除值
    spop(name)
    从集合移除一个成员,并将其返回,说明一下,集合是无序的,所有是随机删除的
  • 删除–指定值删除
    srem(name, values)
    在name对应的集合中删除某些值
r.sadd('set_name','aa')
r.sadd('set_name','bb')
r.sadd('set_name','cc')

print(r.smembers('set_name'))
print(r.scard('set_name'))

print(r.sscan('set_name'))

# 迭代器方式,于增量迭代分批获取元素,避免内存消耗太大
for i in r.sscan_iter('set_name'):
    print(i)

r.spop('set_name')
print('s.spop=>' , r.smembers('set_name'))

r.srem('set_name','cc')
print('s.srem=>' , r.smembers('set_name'))


r.sadd('set1',22,20,40)
r.sadd("set2", 11, 22, 33)
r.smove('set1','set2',40)

print('set1=',r.smembers('set1'))
print('set2=',r.smembers('set2'))
{'aa', 'bb', 'cc'}
3
(0, ['bb', 'cc', 'aa'])
bb
cc
aa
s.spop=> {'aa', 'bb'}
s.srem=> {'aa', 'bb'}
set1= {'20', '22'}
set2= {'33', '40', '22', '11'}

差集

sdiff(keys, *args)
在第一个name对应的集合中且不在其他name对应的集合的元素集合

差集–差集存在一个新的集合中

sdiffstore(dest, keys, *args)
获取第一个name对应的集合中且不在其他name对应的集合,再将其新加入到dest对应的集合中

r.sadd('set1',22,20,40)
r.sadd("set2", 11, 22, 33)
print(r.smembers("set1"))   # 获取集合中所有的成员
print(r.smembers("set2"))
print(r.sdiff("set1", "set2"))   # 在集合set1但是不在集合set2中
print(r.sdiff("set2", "set1"))   # 在集合set2但是不在集合set1中
{'40', '20', '22'}
{'33', '22', '11'}
{'40', '20'}
{'33', '11'}

r.sdiffstore("set3", "set1", "set2")    # 在集合set1但是不在集合set2中
print(r.smembers("set3"))   # 获取集合3中所有的成员
{'40', '20'}

交集

sinter(keys, *args)
获取多一个name对应集合的交集

交集–交集存在一个新的集合中

sinterstore(dest, keys, *args)
获取多一个name对应集合的并集,再将其加入到dest对应的集合中

print(r.sinter("set1", "set2")) # 取2个集合的交集

print(r.sinterstore("set3", "set1", "set2")) # 取2个集合的交集
print(r.smembers("set3"))
{'22'}
1
{'22'}

并集

sunion(keys, *args)
获取多个name对应的集合的并集

并集–并集存在一个新的集合

sunionstore(dest,keys, *args)
获取多一个name对应的集合的并集,并将结果保存到dest对应的集合中

print(r.sunion("set1", "set2")) # 取2个集合的并集

print(r.sunionstore("set3", "set1", "set2")) # 取2个集合的并集
print(r.smembers("set3"))
{'11', '40', '33', '20', '22'}
5
{'11', '40', '33', '20', '22'}

判断是否是集合的成员 类似in

sismember(name, value)
检查value是否是name对应的集合的成员,结果为True和False

print(r.sismember("set1", 40))
True

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值