python 操作 redis

本文深入探讨Redis的多种数据类型,包括String、Hash、List、Set、有序Set等,及其丰富的操作命令。通过Python示例代码展示如何高效地利用Redis解决实际问题,特别强调其在数据缓存和实时数据处理中的应用。

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

Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP客户端,使用很方便,Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。从盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。

redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,Redis是StrictRedis的子类

import redis
import time

# 普通连接方式
r = redis.Redis(host='localhost', port=6379, db=0)
r.set('name', '张三')
print(r.get('name').decode('utf8'))

# 连接池连接方式
pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
r = redis.Redis(connection_pool=pool)
r.set('name1','lisi')
print(r.get('name1').decode('utf8'))

'''
在python中返回的值均是byte类型的,需要decode解码才能转为字符类型,为方便以下给出的结果如无decode均是byte类型
1.String操作
redis中的String在内存中按照一个name对应一个value存储
'''
# set()  默认不存在则创建,存在则修改
r.set('sname1', 'myredis1')  # 普通创建
r.setex('sname2', 'myredis2', 5)  # 设置过期时间(秒)
print(r.get('sname2').decode('utf8'))  # myredis2
time.sleep(5)
print(r.get('sname2').decode('utf8'))  # error

# mset()  批量设置
r.mset(sname1='s1', sname2='s2')
print(r.mget('sname1', 'sname2'))  # [b's1', b's2']

# getset()  设置新值,打印旧值
print(r.get('sname1'))  # myredis1
print(r.getset('sname1', 'hahaha'))  # myredis1
print(r.get('sname1'))  # hahaha

# getrange()  根据字节获取子序列
r.set('name', 'redis')
print(r.getrange('name',0,3))  # redi

# setrange() 修改字符串内容,从制定位置向后替换,新值太长则追加
r.set('name','redis')
r.setrange('name', 1, 'z')
print(r.get('name'))  # rzdis
r.setrange('name', 3, 'zzzzz')
print(r.get('name'))  # rzdzzzzz

# strlen()  返回值的字节长度,一个汉字3字节
r.set('name','redis')
print(r.strlen('name'))  # 5
r.set('name', '张三')
print(r.strlen('name'))  # 6

# incr() 自增
print(r.incr('mount'))  # 16
print(r.get('mount'))  # 16

# decr() 自减
print(r.decr('mount'))  # 15
print(r.get('mount'))  # 15

# append()  对值进行追加
r.set('name','redis')
print(r.get('name'))  # redis
r.append('name','py')
print(r.get('name'))  # redispy

'''
2.Hash操作
redis中的hash在内存中类似于一个name对应一个dict来存储
'''
# hset() 设置一个name对应一个k-v键值对
# hget() 根据name中的key获取value
# hgetall() 获取name中的所有k-v
r.hset('hname','key1','value1')
print(r.hget('hname','key1'))  # value1
print(r.hgetall('hname'))  # {'key1':'value1'}

# hmset() 批量设置键值对
# hmget() 在name中获取多个key的值
d={'a1':'aa','b1':'bb'}
r.hmset('hname', d)
print(r.hget('hname', 'a1'))  # aa
print(r.hmget('hname','a1','b1'))  # ['aa', 'bb']

# hlen() 获取hash中键值对个数
# hkeys() 获取所有的key
# hvals() 获取所有的value
d = {'a1':'aa','b1':'bb'}
r.hmset('hname', d)
print(r.hlen('hname'))  # 3
print(r.hkeys('hname'))  # ['a1','b1','key1']
print(r.hvals('hname'))  # ['aa','bb','value1']

# hexists() 判断name对应的hash是否存在传入的key
print(r.hexists('hname', 'a1'))  # True
print(r.hexists('hname', 'a2'))  # False

# hdel() 删除指定name对应的key所在键值对
r.hdel('hname', 'a1')
print(r.hget('hname', 'a1'))  # None

'''
3.List操作
redis中的list在内存中按照一个name对应一个list来存储
'''
# lpush() 在name对应的list中最左添加元素,rpush()为最右添加
# lpushx() 当name存在时才执行最左添加, rpushx()为name存在时最右添加
r.lpush('lname',2)
r.lpush('lname', 4,6)

# llen() name对应的list元素个数
print(r.llen('lname'))  # 3

# lrange() 分片获取元素
print(r.lrange('lname',0,5))  # [b'6', b'4', b'2']

# linsert() 在name对应的list中某一个值的前或后插入新值
r.linsert('lname','BEFORE','2','ss')
print(r.lrange('lname',0,-1))  # [b'6', b'4', b'ss', b'2']

# lset() 对list中某一个位置重新赋值
r.lset('lname',1,'gg')
print(r.lrange('lname',0,-1))  # [b'6', b'gg', b'ss', b'2']

# lrem() 移除list中指定的值,默认删除所有指定值
r.lrem('lname', 2)
print(r.lrange('lname',0,-1))  # [b'6', b'gg', b'ss']

# lpop() 移除列表左侧第一个元素,并返回移除元素
print(r.lpop('lname'))  # b'6'

# lindex() 根据索引获取列表元素
print(r.lindex('lname', 1))  # b'ss'

# ltrim() 移除列表中没有在改索引之内的值
r.ltrim('lname', 0, 1)

# rpoplpush() 从前一个列表中取出最右元素,同时将其添加到后一个列表的最左边
r.lpush('list1', 1,2)
r.lpush('list2', 3,4)
r.rpoplpush('list1', 'list2')
print(r.lrange('list1', 0, -1))  # [b'2']
print(r.lrange('list2', 0, -1))  # [b'1', b'4', b'3']

# blpop() 将多个列表排列,按照从左到右去移除各个列表内的元素
r.lpush("list_name",3,4,5)
r.lpush("list_name1",3,4,5)
while True:
    print(r.blpop(['list_name', 'list_name1'], timeout=0))
    print(r.lrange("list_name", 0, -1), r.lrange("list_name1", 0, -1))

# (b'list_name', b'5')
# [b'4', b'3', b'2', b'3'] [b'5', b'4', b'3']
# (b'list_name', b'4')
# [b'3', b'2', b'3'] [b'5', b'4', b'3']
# (b'list_name', b'3')
# [b'2', b'3'] [b'5', b'4', b'3']
# (b'list_name', b'2')
# [b'3'] [b'5', b'4', b'3']
# (b'list_name', b'3')
# [] [b'5', b'4', b'3']
# (b'list_name1', b'5')
# [] [b'4', b'3']
# (b'list_name1', b'4')
# [] [b'3']
# (b'list_name1', b'3')
# [] []

'''
4.Set操作
集合,不含有重复值
'''
# sadd() 给name对应的集合中添加元素
r.sadd('setname', 'aa')
r.sadd('setname', 'aa', 'bb')

# smembers() 获取集合所有成员
print(r.smembers('setname'))  # {b'bb', b'aa'}

# scard() 获取集合中的元素个数
print(r.scard('setname'))  # 2

# sdiff() 差集,在第一个name集合中存在,且不在其他name集合中的,元素集合
r.sadd('setname1','a','b','c')
r.sadd('setname2', 'a','b','cc')
print(r.sdiff('setname1', 'setname2'))  # {b'c'}

# sinter() 交集,多个name集合的交集
r.sadd('setname1','a','b','c')
r.sadd('setname2', 'a','b','cc')
print(r.sinter('setname1','setname2'))  # {b'a', b'b'}

# sunion() 并集,多个集合的并集
print(r.sunion('setname','setname1', 'setname2'))  # {b'c', b'bb', b'aa', b'b', b'cc', b'a'}

# sismember() 检查value是否在集合中
print(r.sismember('setname1', 'b'))  # True

# smove() 将元素从一个集合移动到另一个集合
print(r.smembers('setname1'))  # {b'b', b'a', b'c'}
r.smove('setname1','setname2', 'c')
print(r.smembers('setname1'))  # {b'b', b'a'}

# spop(name) 从集合最右侧移除一个元素并返回
srem(name, values) 从集合中删除某些值
srandmember(name, numbers) 从集合中随机获取numbers个元素
print(r.srandmember('setname2', 2))  # [b'b', b'cc']

'''
5.有序集合
在集合的基础上,根据元素分数,为元素排序
'''
# zadd() 有序集合添加元素
r.zadd('zsetname', 'a', 5, 'b', 1)
r.zadd('zsetname1', a=5, b=1, c=3)

# zcard(name) 获取有序集合中元素数量
print(r.zcard('zsetname'))  # 2

# zcount(name, min, max) 获取有序集合中分数在[min, max]中的个数
print(r.zcount('zsetname1', 1, 3))  # 2

# zincrby(name, value, amount) 自增有序集合内value对应的分数
r.zincrby('zsetname','b', amount=2)

# zrange() 按照索引获取有序集合内的元素, 默认按照分数升序排列
print(r.zrange('zsetname', 0, -1, desc=False, withscores=True))  # [(b'b', 3.0), (b'a', 5.0)]

# zrank(name, value) 获取value在name中的索引位置
print(r.zrank('zsetname', 'a'))  # 1

# zscore(name, value) 获取value在name中的分数
print(r.zscore('zsetname', 'a'))  # 5.0

# zrem(name, values) 从有序集合中移除某些值
r.zrem('zsetname', 'a', 'b')
print(r.zrange('zsetname', 0, -1))  # []

'''
6.其他操作
'''
# delete(*names) 根据name删除redis中任意类型
# exists(name)  检测redis的name是否存在
# keys(pattern='*') 根据通配符获取redis的name列表
# print(r.keys(pattern='*'))  # [b'setName', b'name', b'sn2']
# expire(name, time) 为某个name设置过期时间
# rename(src, dst) 重命名
# move(name, db) 将redis的某个值移动到指定的db下
# randomkey() 随机获取redis的name
# type(name) 获取name对应的类型

'''
7.管道
redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,
如果想在一次请求中执行多个命令,可以使用pipline管道实现,默认情况下一次pipline是原子性操作
'''
pipe = r.pipeline(transaction=True)
r.set('name', 'a')
r.set('name', 'b')
pipe.execute()
print(r.get('name'))  # b'b'

'''
8.发布和订阅
首先定义一个RedisHelper类,连接redis,定义频道为monitor,定义发布publish和订阅subscribe方法
'''
class RedisHelper:
    def __init__(self):
        self._conn = redis.Redis(host='localhost', port=6379)
        self.channel = 'monitor'  # 定义频道名称

    def publish(self, msg):
        # 定义发布方法
        self._conn.publish(self.channel, msg)
        return True

    def subScribe(self):
        # 定义订阅方法
        pub = self._conn.pubsub()
        pub.subscribe(self.channel)
        pub.parse_response()
        return pub

# # 发布者 pub.py
# from redistest import RedisHelper
# puber = RedisHelper()
# puber.publish('hello')
#
# # 订阅者 sub.py
# from redistest import RedisHelper
# suber = RedisHelper()
# suber_redis = suber.subScribe()
# while True:
#     msg = suber_redis.parse_response()
#     print(msg)  # [b'message', b'monitor', b'hello']

感谢原作者整理,我个人重新手打一遍。

内容概要:本文详细探讨了基于MATLAB/SIMULINK的多载波无线通信系统仿真及性能分析,重点研究了以OFDM为代表的多载波技术。文章首先介绍了OFDM的基本原理和系统组成,随后通过仿真平台分析了不同调制方式的抗干扰性能、信道估计算法对系统性能的影响以及同步技术的实现与分析。文中提供了详细的MATLAB代码实现,涵盖OFDM系统的基本仿真、信道估计算法比较、同步算法实现和不同调制方式的性能比较。此外,还讨论了信道特征、OFDM关键技术、信道估计、同步技术和系统级仿真架构,并提出了未来的改进方向,如深度学习增强、混合波形设计和硬件加速方案。; 适合人群:具备无线通信基础知识,尤其是对OFDM技术有一定了解的研究人员和技术人员;从事无线通信系统设计与开发的工程师;高校通信工程专业的高年级本科生和研究生。; 使用场景及目标:①理解OFDM系统的工作原理及其在多径信道环境下的性能表现;②掌握MATLAB/SIMULINK在无线通信系统仿真中的应用;③评估不同调制方式、信道估计算法和同步算法的优劣;④为实际OFDM系统的设计和优化提供理论依据和技术支持。; 其他说明:本文不仅提供了详细的理论分析,还附带了大量的MATLAB代码示例,便于读者动手实践。建议读者在学习过程中结合代码进行调试和实验,以加深对OFDM技术的理解。此外,文中还涉及了一些最新的研究方向和技术趋势,如AI增强和毫米波通信,为读者提供了更广阔的视野。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值