Python3之redis使用
Posted ExplorerMan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python3之redis使用相关的知识,希望对你有一定的参考价值。
简介
redis是一个key-value存储系统,和Memcache类似,它支持存储的value类型相对更多,包括string(字符串),list(列表),set(集合),zset(有序集合),hash(哈希类型)。这些数据类型都支持push/pop,add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序,与memcached一样,为了保证效率,数据都是缓冲在内存中。区别是redis会周期性的把更新的数据写入磁盘或把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
备注:默认redis有16个数据库,即db0~db15, 一般存取数据如果不指定库的话,默认都是存在db0中。
安装Redis模块
python想操作redis,需要安装第三方模块。
1
2
3
4
5
6
|
sudo pip3 install redis or sudo easy_install redis or 源码安装 详见:https: / / github.com / WoLpH / redis - py |
Redis模块基本使用
redis 模块使用可以分类为:
- 连接方式
- 连接池
- 操作
- String操作
- Hash操作
- List操作
- Set操作
- Sort Set操作
- 管道
- 发布订阅
(1)操作模式
redis提供两个类Redis和StrictRedis, StrictRedis用于实现大部分官方的命令,Redis是StrictRedis的子类,用于向后兼用旧版本。
1
2
3
4
5
6
7
8
9
10
|
#!/usr/bin/env python3 #coding:utf8 import redis r = redis.Redis(host = \'0.0.0.0\' , port = 6379 ) # r = redis.StrictRedis(host=\'0.0.0.0\', port=6379) # 如果要指定数据库,则 r = redis.StrictRedis(host=\'0.0.0.0\', port=6379, db=0) r. set ( \'name\' , \'test\' ) print (r.get( \'name\' )) # 输出结果 b \'test\' |
str 还是 byte? 通过上面的简单测试,看到redis 取出的结果默认是字节,我们可以设定decode_responses=True 改成字符串。
1
2
3
4
5
6
7
|
import redis r = redis.StrictRedis(host = \'0.0.0.0\' , port = 6379 , decode_responses = True ) r. set ( \'c\' , \'python\' ) ret = r.get( \'c\' ) print (ret , type (ret)) # 结果 python < class \'str\' > |
关于编码
1
2
3
4
|
class redis.StrictRedis(host = \'localhost\' , port = 6379 , db = 0 , password = None , socket_timeout = None , connection_pool = None , charset = \'utf-8\' , errors = \'strict\' , decode_responses = False , unix_socket_path = None ) # 默认redis入库编码是utf-8,如果要修改的话,需要指明 charset 和 decode_responsers 为True. 下面是GBK编码。 class redis.StrictRedis (host = \'localhost\' , port = 6379 , db = 0 , password = None , socket_timeout = None ,connection_pool = None , charset = \'GBK \' , errors = \'strict\' , decode_responses = True ) |
(2)连接池
redis使用connection pool来管理对一个redis server 的所有连接,避免每次建立,释放连接的开销,默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。
1
2
3
4
5
6
7
|
import redis pool = redis.ConnectionPool(host = \'0.0.0.0\' , port = 6379 ) r = redis.Redis(connection_pool = pool) r. set ( \'age\' , \'16\' ) print (r.get( \'age\' )) # 结果 b \'16\' |
1
2
3
4
5
6
7
8
|
# 使用 StrictRedis 连接池 import redis pool = redis.ConnectionPool(host = \'47.92.114.20\' , port = 6379 ) r = redis.StrictRedis(connection_pool = pool) r. set ( \'age\' , \'16\' ) print (r.get( \'age\' )) # 结果 b \'16\' |
(3)数据操作
String 操作
redis中的String在在内存中按照一个name对应一个value来存储的。
- set(name, value, ex=None, px=None, nx=False, xx=False)
1
2
3
4
5
6
7
8
9
10
11
12
|
在Redis中设置值,默认,不存在则创建,存在则修改 参数: ex,过期时间(秒) px,过期时间(毫秒) nx,如果设置为 True ,则只有name不存在时,当前 set 操作才执行 xx,如果设置为 True ,则只有name存在时,岗前 set 操作才执行 import redis r = redis.StrictRedis(host = \'0.0.0.0\' , port = 6379 ) r. set ( \'age\' , \'20\' ) print (r.get( \'age\' )) # 结果: b \'20\' |
- setnx(name,value)
1
2
3
4
5
6
7
8
|
设置值,只有name不存在时,执行设置操作(添加) import redis r = redis.StrictRedis(host = \'47.92.114.20\' , port = 6379 ) r.setnx( \'a\' , \'python\' ) # 第一次设置时,键值a不存在 r.setnx( \'a\' , \'golang\' ) # 再次设置,键值a已经存在了 print (r.get( \'a\' )) # 结果 b \'python\' |
- setex(name,value,time)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# 设置值 # 参数: # time,过期时间(数字秒 或 timedelta对象) #!/usr/bin/env python3 #coding:utf8 import redis r = redis.Redis(host = \'0.0.0.0\' , port = 6379 ) r.setex( \'name\' , \'tom\' , \'1\' ) print (r.get( \'name\' )) 结果: b \'yaoyao\' 当超过一秒 print (r.get( \'name\' )) 结果: None |
- psetex(name,time_ms,value)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# 设置值 # 参数: # time_ms,过期时间(数字毫秒 或 timedelta对象) import redis import time r = redis.Redis(host = \'0.0.0.0\' , port = 6379 ) r.psetex( \'name\' , \'1\' , \'test\' ) print (r.get( \'name\' )) time.sleep( 0.1 ) print (r.get( \'name\' )) 结果: b \'test\' None |
- mset(*args, **kwargs)
1
2
3
4
5
6
7
8
|
#批量设置值 #如: #mset(k1=\'v1\', k2=\'v2\') import redis r = redis.Redis(host = \'0.0.0.0\' , port = 6379 ) r.mset(name = \'tom\' ,age = \'18\' ) print (r.get( \'name\' )) print (r.get( \'age\' )) |
- get(name)
1
2
3
4
5
6
|
#获取值 import redis r = redis.Redis(host = \'0.0.0.0\' , port = 6379 ) r.mset(name = \'tom\' ,age = \'18\' ) print (r.get( \'name\' )) print (r.get( \'age\' )) |
- getrange(key, start, end)
1
2
3
4
5
6
7
8
9
10
11
12
|
# 获取子序列(根据字节获取,非字符) # 参数: # name,Redis 的 name # start,起始位置(字节) # end,结束位置(字节) import redis r = redis.Redis(host = \'0.0.0.0\' , port = 6379 ) r. set ( \'name\' , \'tomhhaha\' ) res = r.getrange( \'name\' , 0 , 3 ) print (res) 结果: b \'tomh\' |
- settrange(name,offset,value)
1
2
3
4
5
6
7
8
9
10
11
|
# 修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加) # 参数: # offset,字符串的索引,字节(一个汉字三个字节) # value,要设置的值 import redis r = redis.Redis(host = \'0.0.0.0\' , port = 6379 ) r. set ( \'name\' , \'tomname\' ) r.setrange( \'name\' , 0 , \'python\' ) print (r.get( \'name\' )) 结果: b \'pythone\' |
- setbit(name,offset,value)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# 对name对应值的二进制表示的位进行操作 # 参数: # name,redis的name # offset,位的索引(将值变换成二进制后再进行索引) # value,值只能是 1 或 0 # 注:如果在Redis中有一个对应: n1 = "foo", #那么字符串foo的二进制表示为:01100110 01101111 01101111 #所以,如果执行 setbit(\'n1\', 7, 1),则就会将第7位设置为1, #那么最终二进制则变成 01100111 01101111 01101111,即:"goo" # 扩展,转换二进制表示:# source = "武沛齐" import redis r = redis.Redis(host = \'0.0.0.0\' , port = 6379 ) r. set ( \'name\' , \'python\' ) print (r.get( \'name\' )) r.setbit( \'name\' , \'7\' , \'1\' ) print (r.get( \'name\' )) 结果: b \'python\' b \'mython\' |
- getbit(name,offset)
1
2
3
4
5
6
7
|
# 获取name对应的值的二进制表示中的某位的值 (0或1) import redis r = redis.Redis(host = \'0.0.0.0\' , port = 6379 ) r. set ( \'name\' , \'python\' ) print (r.getbit( \'name\' , \'2\' )) 结果: 1 |
- bitcount(key,start=None,end=None)
1
2
3
4
5
6
7
8
9
10
11
|
# 获取name对应的值的二进制表示中 1 的个数 # 参数: # key,Redis的name # start,位起始位置 # end,位结束位置 import redis r = redis.Redis(host = \'0.0.0.0\' , port = 6379 ) r. set ( \'name\' , \'python\' ) rint(r.bitcount( \'name\' , \'0\' , \'5\' )) 结果: 27 |
- bitop(operation,dest,*keys)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# 获取多个值,并将值做位运算,将最后的结果保存至新的name对应的值 # 参数: # operation,AND(并) 、 OR(或) 、 NOT(非) 、 XOR(异或) # dest, 新的Redis的name # *keys,要查找的Redis的name # 如: bitop( "AND" , \'new_name\' , \'n1\' , \'n2\' , \'n3\' ) # 获取Redis中n1,n2,n3对应的值,然后讲所有的值做位运算(求并集),然后将结果保存 new_name 对应的值中 import redis r = redis.Redis(host = \'0.0.0.0\' , port = 6379 ) r. set ( \'n1\' , \'11\' ) r. set ( \'n2\' , \'21\' ) r. set ( \'n3\' , \'11\' ) r.bitop( \'AND\' , \'newname\' , \'n1\' , \'n2\' , \'n3\' ) print (r.get( \'newname\' )) 结果: b \'01\' |
- strlen(name)
1
2
3
4
5
6
7
|
# 返回name对应值的字节长度(一个汉字3个字节) import redis r = redis.Redis(host = \'0.0.0.0\' , port = 6379 ) r. set ( \'name\' , \'python\' ) print (r.strlen( \'name\' )) 结果: 6 |
- incr(self, name, amount = 1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。 # 参数: # name,Redis的name # amount,自增数(必须是整数) # 注:同incrby import redis r = redis.Redis(host = \'0.0.0.0\' , port = 6379 ) r. set ( \'age\' , \'1\' ) print (r.incr( \'age\' , \'2\' )) 结果: 3 如果没有 print (r.incr( \'ageno\' , \'2\' )) 结果 2 |
- incrbyfloat(self,name,amount=1.0)
1
2
3
4
5
6
7
8
9
10
|
# 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增。 # 参数: # name,Redis的name # amount,自增数(浮点型) import redis r = redis.Redis(host = \'0.0.0.0\' , port = 6379 ) r. set ( \'byfloat\' , \'1\' ) print (r.incrbyfloat( \'byfloat\' , \'2.0\' )) 结果: 3.0 |
- decr(self, name, amount=1)
1
2
3
4
5
6
7
8
|
# 自减 name对应的值,当name不存在时,则创建name=amount,否则,则自减。 # 参数: # name,Redis的name # amount,自减数(整数) import redis r = redis.Redis(host = \'0.0.0.0\' , port = 6379 ) r. set ( \'age\' , \'11\' ) print (r.decr( \'age\' , \'2\' )) |
- append(key,value)
1
2
3
4
5
6
7
8
9
10
11
12
|
# 在redis name对应的值后面追加内容 # 参数: key, redis的name value, 要追加的字符串 import redis |