目录
起步
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""string类型操作
二进制安全
"""
import redis
pool = redis.ConnectionPool(host='192.168.1.104', password='hardy9sap', decode_responses=True)
rs = redis.Redis(connection_pool=pool)
is_connected = rs.ping()
提醒:
在
Python3
,可以传number
/bytes
/string
这三类(有错误,欢迎指正…(╹▽╹))
set / setnx / setex / psetex
set(name, value, ex=None, px=None, nx=False, xx=False)
参数:
参数 | 解释 |
---|---|
ex | 过期时间(秒) |
px | 过期时间(毫秒) |
nx | 如果设置为True,则只有name不存在时,当前set操作才执行,并且返回True,否则返回None |
xx | 如果设置为True,则只有name存在时,当前set操作才执行,并且返回True,否则返回None |
快捷方法:
setnx(name, value):设置值,只有在name不存在是才执行操作,并且返回True,否则返回False
setex(name, value, time):设置值过期时间,单位为秒
psetex(name, time_ms, value):设置值,过期时间为毫秒
说明:
关键字传参并不是必须的,可以位置传参,我只是习惯用关键字形式
示例:
-
设置一个名为
redis:method:set1
,值为sets
的 string key等价的redis命令:
set redis:method:set 'sets'
rsp = rs.set(name='redis:method:set', value='sets') print(rsp) # True,表示当前set操作执行成功
-
在
name
不存在的情况下,设置一个名为redis:method:set
,值为sets
,过期时间为3
秒的 string key等价的redis命令:
set redis:method:set 'sets' EX 3 NX
redis中的
nil
数据类型 对应 python3 中的None
rsp = rs.set(name='redis:method:set', value='sets', ex=3, nx=True) print(rsp) # 返回None,因为redis:method:set已经存在了
-
在
name
存在的情况下,设置一个名为redis:method:set
,值为sets
,过期时间为3000
毫秒的 string keyrsp = rs.set(name='redis:method:set', value='sets', px=3000, xx=True) print(rsp) # 返回True,因为redis:method:set已存在,符合条件
-
setnx
没有设置过期时间的参数,只能结合expire
方法等价的redis命令:
setnx redis:method:setnx 'seetnx'
rsp = rs.setnx(name='redis:method:setnx', value='setnx') print(rsp)
-
setex
又有设置过期时间的参数,(〃>皿<),(最后仔细一想,意思并不是说在name存在的情况下设置)(而是设置过期时间,那就解释得通了)(我老是喜欢把ex看成是exists的缩写,其实是expire!!!)等价的redis命令:
setex redis:method:setex 3 'setex'
额外说明:
time
参数写在中间,纯粹是为了记忆redissetex
命令方便(对于我个人而言)rsp = rs.setex(name='redis:method:setex', time=3, value='setex') print(rsp) # True
-
psetex
一样的道理rsp = rs.psetex(name='redis:method:psetex', time_ms=3000, value='psetex') print(rsp) # True
mset / msetnx
mset(mapping),mapping参数接受一个字典结构,批量设置多个值
msetnx(mapping),在所有的 key 都不存在的情况下,成功设置时,才返回True,
只要有一个key存在,则设置失败,返回False
示例:
mset
rsp = rs.mset(mapping={
'redis:method:set1': 'set1',
'redis:method:set2': 'set2',
'redis:method:set3': 'set3',
})
print(rsp) # True
msetnx
rsp = rs.msetnx(mapping={
'redis:method:set1': 'set1',
'redis:method:set2': 'set2',
'redis:method:set3': 'set3',
})
print(rsp) # False,因为都存在呀
get
get(name),获取name的value
如果name不存在,返回None
如果name存在,但name不是string类型,报错redis.exceptions.ResponseError
redis.exceptions.ResponseError: WRONGTYPE Operation against a key holding the wrong kind of value
存在,并且类型是string:
# 存在,并且类型是string
rsp = rs.get(name='redis:method:set1')
print(rsp) # set1
不存在:
rsp = rs.get(name='wdnmd')
print(rsp) # None
存在,但类型不是string类型:
# 注:测试的 test 是list类型
try:
rsp = rs.get(name='test')
except redis.exceptions.ResponseError as e:
print(e)
else:
print(rsp)
mget
mget(keys, *args),一次性获取多个值,以list形式返回
写法一:
keys
参数
rsp = rs.mget(keys=('redis:method:set1', 'redis:method:set2', 'redis:method:set3'))
print(rsp) # ['wdnmd', 'set2', 'set3']
写法二:
直接位置传参
# 提醒:获取不存在的key,当前那个key返回None
rsp = rs.mget(*('redis:method:set1111', 'redis:method:set2', 'redis:method:set3'))
print(rsp) # [None, 'set2', 'set3']
getrange
getrange(key, start, end),获取key的value其中一部分[start, end](闭合区间)。
0. 从0开始
1. start、end都支持负索引
例如:getrange(key, start=0, end=4)
getrange(key, start=0, end=-1)
getrange(key, start=-4, end=-2),注意跟Python中区别开来
2. [start, end]是闭合区间
3. 如果start超过了value的索引范围,直接返回空字符串''
如果是end超过了value的索引范围,则有后续有多少就获取多少
4. key不存在,返回空字符串''
示例:
rsp = rs.getrange(key='redis:method:set1', start=0, end=4)
print(rsp) # wdnmd
rsp = rs.getrange(key='redis:method:set1', start=0, end=-1)
print(rsp) # wdnmd
rsp = rs.getrange(key='redis:method:set1', start=-4, end=-2)
print(rsp) # dnm
getset
getset(name, value),先获取name的值,并且返回,
再给name赋值一个的值为value
(先获取,再赋值)
返回值有三种结果:参照get
示例:
rsp = rs.getset(name='redis:method:set1', value='wdnmd')
print(rsp) # set1
print(rs.get(name='redis:method:set1')) # wdnmd
setrange
setrange(name, offset, value),
用指定的字符串value覆盖给定 name 所储存的字符串值,
覆盖的起始位置从偏移量 offset 开始,并且返回覆盖之后的字符串的字节总长度
注意: 返回的是
字节长度
,不是字符长度
rsp = rs.setrange(name='redis:method:set1', offset=0, value='Long live China.')
print(rsp) # 16,返回设置之后的字符串字节总长度
print(rs.get(name='redis:method:set1'))
append
append(key, value)
将value追加到key原有的值后面,并且返回追加之后的总字节长度;
如果key不存在,就赋值并且返回字符串字节总长度
示例:
rsp = rs.append(key='redis:method:set1', value='中国万岁。')
print(rsp)
print(rs.get(name='redis:method:set1'))
strlen
strlen(name)
获取key的value的字节长度,不存在返回0,存在但类型不是string,报错
utf-8编码下,一个汉字3个字节
存在,并且类型是string
rsp = rs.strlen(name='redis:method:set1')
print(rsp) # 字节数,34
不存在
rsp = rs.strlen(name='wdnmd')
print(rsp) # 0
存在,但类型不是string
try:
rsp = rs.strlen(name='test')
except redis.exceptions.ResponseError as e:
print(e) # WRONGTYPE Operation against a key holding the wrong kind of value
else:
print(rsp)
incr
incr(name, amount=1)
将name的value自增1
1. amount默认为1
2. amount可以为负数
3. amount必须为整型
4. 原本的value值也必须为整型
5. 如果一开始name不存在,那么 name 的值会先被初始化为 0 ,然后再执行自增操作
示例:
rsp = rs.incr(name='redis:incr', amount=1)
print(rsp, rsp.__class__) # 1, int
rsp = rs.incr(name='redis:incr', amount=-1)
print(rsp) # 0
rsp = rs.incr(name='redis:incr', amount=1.5)
print(rsp) # value is not an integer or out of range
rsp = rs.incr(name='testincr', amount=1)
print(rsp) # 原本的value为1.5,报错
decr
跟incr一样,只是做自减操作
decr(name, amount=1)
将name的value递减1
1. amount默认为1
2. amount可以为负数
3. amount必须为整型
4. 原本的value值也必须为整型
5. 如果一开始name不存在,那么 name 的值会先被初始化为 0 ,然后再执行递减操作
示例:
rsp = rs.decr(name='redis:incr', amount=1)
print(rsp, rsp.__class__)
rsp = rs.decr(name='redis:incr', amount=-1)
print(rsp) # 0
rsp = rs.decr(name='redis:incr', amount=1.5)
print(rsp) # value is not an integer or out of range
rsp = rs.decr(name='testincr', amount=1)
print(rsp) # 原本的value为1.5,报错
incrby
跟incr使用一样
incrby(name, amount=1)
decrby
跟decr使用一样
decrby(name, amount=1)
incrbyfloat
incrbyfloat(name, amount=1.0)
将name的value自增1.0
1. amount默认为1.0
2. amount可以为负数
3. amount可以为整数或者浮点数
4. 原本的value值也可以为整数或者浮点数
5. 如果一开始name不存在,那么 name 的值会先被初始化为 0 ,然后再执行递减操作
示例:
rsp = rs.incrbyfloat(name='redis:incr', amount=1.0)
print(rsp) # 4.0
rsp = rs.incrbyfloat(name='redis:incr', amount=-1.2)
print(rsp) # 2.8
rsp = rs.incrbyfloat(name='testincr', amount=2.5)
print(rsp) # 4.0
setbit
setbit(name, offset, value):对name对应值的二进制表示的位进行操作
offset必须为整型,value必须为0 or 1,当然在Python中,int or str都可以
每次返回上次的value
0 1 2 3 4 5 6 7
0 1 1 0 1 0 1 1
是从左往右数,不是平常的从右往左数
示例:
rsp = rs.setbit(name='name', offset='6', value='1')
print(rs.get(name='name'))
getbit
getbit(name, offset):获取name对应的二进制位表示的值,只能是0或1
示例:
rsp = rs.getbit(name='name', offset=4)
print(rsp)
整体代码
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""string类型操作
二进制安全
"""
import redis
pool = redis.ConnectionPool(host='192.168.1.104', password='hardy9sap', decode_responses=True)
rs = redis.Redis(connection_pool=pool)
is_connected = rs.ping()
# 在Python3,只能传number / bytes / string这三类
# string数据类型操作
# 1. set / setnx / setex
# ============================================================
# set(name, value, ex=None, px=None, nx=False, xx=False)
# ex,过期时间(秒)
# px,过期时间(毫秒)
# nx,如果设置为True,则只有name不存在时,当前set操作才执行,并且返回True,否则返回None
# xx,如果设置为True,则只有name存在时,当前set操作才执行,并且返回True,否则返回None
#
# 快捷方法:
# setnx(name, value):设置值,只有在name不存在是才执行操作,并且返回True,否则返回False
# setex(name, value, time):设置值过期时间,单位为秒
# psetex(name, time_ms, value):设置值,过期时间为毫秒
# ===========================================================
# 说明:关键字传参并不是必须的,可以位置传参,我只是习惯用关键字形式
# if is_connected:
# # 设置一个名为redis:method:set1,值为sets的string key
# # 等价的redis命令:set redis:method:set 'sets'
# # rsp = rs.set(name='redis:method:set', value='sets')
# # print(rsp) # True,表示当前set操作执行成功
#
# # 在name不存在的情况下,设置一个名为redis:method:set,值为sets,过期时间为3秒的string key
# # 等价的redis命令:set redis:method:set 'sets' EX 3 NX
# # redis中的nil数据类型对应python3中的None
# # rsp = rs.set(name='redis:method:set', value='sets', ex=3, nx=True)
# # print(rsp) # 返回None,因为redis:method:set已经存在了
#
# # 在name存在的情况下,设置一个名为redis:method:set,值为sets,过期时间为3000毫秒的string key
# # rsp = rs.set(name='redis:method:set', value='sets', px=3000, xx=True)
# # print(rsp) # 返回True,因为redis:method:set已存在,符合条件
#
# # setnx没有设置过期时间的参数,只能结合expire方法
# # 等价的redis命令:setnx redis:method:setnx 'seetnx'
# # rsp = rs.setnx(name='redis:method:setnx', value='setnx')
# # print(rsp)
#
# # setex又有设置过期时间的参数,(〃>皿<),(最后仔细一想,意思并不是说在name存在的情况下设置)
# # (而是设置过期时间,那就解释得通了)(我老是喜欢把ex看成是exists的缩写,其实是expire!!!)
# # 等价的redis命令:setex redis:method:setex 3 'setex'
# # 额外说明:time参数写在中间,纯粹是为了记忆redis setex命令方便(对于我个人而言)
# # rsp = rs.setex(name='redis:method:setex', time=3, value='setex')
# # print(rsp) # True
#
# # psetex一样的道理
# # rsp = rs.psetex(name='redis:method:psetex', time_ms=3000, value='psetex')
# # print(rsp) # True
# pass
# 2. mset / msetnx
# =======================================================
# mset(mapping),mapping参数接受一个字典结构,批量设置多个值
# msetnx(mapping),在所有的 key 都不存在的情况下,成功设置时,才返回True,
# 只要有一个key存在,则设置失败,返回False
# =======================================================
# if is_connected:
# rsp = rs.mset(mapping={
# 'redis:method:set1': 'set1',
# 'redis:method:set2': 'set2',
# 'redis:method:set3': 'set3',
# })
# print(rsp) # True
#
# rsp = rs.msetnx(mapping={
# 'redis:method:set1': 'set1',
# 'redis:method:set2': 'set2',
# 'redis:method:set3': 'set3',
# })
# print(rsp) # False,因为都存在呀
# 3. get
# =============================================================================================================
# get(name),获取name的value
# 如果name不存在,返回None
# 如果name存在,但name不是string类型,报错redis.exceptions.ResponseError
# redis.exceptions.ResponseError: WRONGTYPE Operation against a key holding the wrong kind of value
# =============================================================================================================
# if is_connected:
# # 存在,并且类型是string
# rsp = rs.get(name='redis:method:set1')
# print(rsp) # set1
#
# # 不存在
# rsp = rs.get(name='wdnmd')
# print(rsp)
#
# # 存在,但类型不是string类型
# # 注:测试的 test 是list类型
# try:
# rsp = rs.get(name='test')
# except redis.exceptions.ResponseError as e:
# print(e)
# else:
# print(rsp)
# 4. mget
# =========================================================
# mget(keys, *args),一次性获取多个值,以list形式返回
# =========================================================
# if is_connected:
# # 写法一:
# rsp = rs.mget(keys=('redis:method:set1', 'redis:method:set2', 'redis:method:set3'))
# print(rsp) # ['wdnmd', 'set2', 'set3']
#
# # 写法二:直接位置传参
# # 提醒:获取不存在的key,当前那个key返回None
# rsp = rs.mget(*('redis:method:set1111', 'redis:method:set2', 'redis:method:set3'))
# print(rsp) # [None, 'set2', 'set3']
# 5. getrange
# ===========================================================================
# getrange(key, start, end),获取key的value其中一部分[start, end](闭合区间)。
# 0. 从0开始
# 1. start、end都支持负索引
# 例如:getrange(key, start=0, end=4)
# getrange(key, start=0, end=-1)
# getrange(key, start=-4, end=-2)
# 2. [start, end]是闭合区间
# 3. 如果start超过了value的索引范围,直接返回空字符串''
# 如果是end超过了value的索引范围,则有后续有多少就获取多少
# 4. key不存在,返回空字符串''
# ============================================================================
# if is_connected:
# rsp = rs.getrange(key='redis:method:set1', start=0, end=4)
# print(rsp) # wdnmd
#
# rsp = rs.getrange(key='redis:method:set1', start=0, end=-1)
# print(rsp) # wdnmd
#
# rsp = rs.getrange(key='redis:method:set1', start=-4, end=-2)
# print(rsp) # dnm
# 6. getset
# ================================================
# getset(name, value),先获取name的值,并且返回,
# 再给name赋值一个的值为value
# (先获取,再赋值)
# 返回值有三种结果:参照get
# ================================================
# if is_connected:
# rsp = rs.getset(name='redis:method:set1', value='wdnmd')
# print(rsp) # set1
# print(rs.get(name='redis:method:set1')) # wdnmd
# 7. setrange
# ==================================================================
# setrange(name, offset, value),
# 用指定的字符串value覆盖给定 name 所储存的字符串值,
# 覆盖的起始位置从偏移量 offset 开始,并且返回覆盖之后的字符串的字节总长度
# ==================================================================
# if is_connected:
# rsp = rs.setrange(name='redis:method:set1', offset=0, value='Long live China.')
# print(rsp) # 16,返回设置之后的字符串字节总长度
#
# print(rs.get(name='redis:method:set1'))
# 8. append
# =======================================================
# append(key, value)
# 将value追加到key原有的值后面,并且返回追加之后的总字节长度;
# 如果key不存在,就赋值并且返回字符串字节总长度
# =======================================================
# if is_connected:
# rsp = rs.append(key='redis:method:set1', value='中国万岁。')
# print(rsp)
#
# print(rs.get(name='redis:method:set1'))
# 9. strlen
# ==========================================================
# strlen(name)
# 获取key的value的字节长度,不存在返回0,存在但类型不是string,报错
# utf-8编码下,一个汉字3个字节
# ==========================================================
# if is_connected:
# # 存在,并且类型是string
# rsp = rs.strlen(name='redis:method:set1')
# print(rsp) # 字节数,34
#
# # 不存在
# rsp = rs.strlen(name='wdnmd')
# print(rsp) # 0
#
# # 存在,但类型不是string
# try:
# rsp = rs.strlen(name='test')
# except redis.exceptions.ResponseError as e:
# print(e) # WRONGTYPE Operation against a key holding the wrong kind of value
# else:
# print(rsp)
# 10. incr
# =====================================================================
# incr(name, amount=1)
# 将name的value自增1
# 1. amount默认为1
# 2. amount可以为负数
# 3. amount必须为整型
# 4. 原本的value值也必须为整型
# 5. 如果一开始name不存在,那么 name 的值会先被初始化为 0 ,然后再执行自增操作
# =====================================================================
# if is_connected:
# rsp = rs.incr(name='redis:incr', amount=1)
# print(rsp, rsp.__class__) # 1, int
# #
# rsp = rs.incr(name='redis:incr', amount=-1)
# print(rsp) # 0
#
# rsp = rs.incr(name='redis:incr', amount=1.5)
# print(rsp) # value is not an integer or out of range
#
# rsp = rs.incr(name='testincr', amount=1)
# print(rsp) # 原本的value为1.5,报错
# 10. decr
# =====================================================================
# 跟incr一样,只是做自减操作
# decr(name, amount=1)
# 将name的value递减1
# 1. amount默认为1
# 2. amount可以为负数
# 3. amount必须为整型
# 4. 原本的value值也必须为整型
# 5. 如果一开始name不存在,那么 name 的值会先被初始化为 0 ,然后再执行递减操作
# =====================================================================
# if is_connected:
# rsp = rs.decr(name='redis:incr', amount=1)
# print(rsp, rsp.__class__)
#
# rsp = rs.decr(name='redis:incr', amount=-1)
# print(rsp) # 0
#
# rsp = rs.decr(name='redis:incr', amount=1.5)
# print(rsp) # value is not an integer or out of range
#
# rsp = rs.decr(name='testincr', amount=1)
# print(rsp) # 原本的value为1.5,报错
# 11. incrby
# =======================
# 跟incr使用一样
# incrby(name, amount=1)
# =======================
# 12. decrby
# ========================
# 跟decr使用一样
# decrby(name, amount=1)
# ========================
# 13. incrbyfloat
# ================================
# incrbyfloat(name, amount=1.0)
# 将name的value自增1.0
# 1. amount默认为1.0
# 2. amount可以为负数
# 3. amount可以为整数或者浮点数
# 4. 原本的value值也可以为整数或者浮点数
# 5. 如果一开始name不存在,那么 name 的值会先被初始化为 0 ,然后再执行递减操作
# ================================
# if is_connected:
# rsp = rs.incrbyfloat(name='redis:incr', amount=1.0)
# print(rsp) # 4.0
#
# rsp = rs.incrbyfloat(name='redis:incr', amount=-1.2)
# print(rsp) # 2.8
#
# rsp = rs.incrbyfloat(name='testincr', amount=2.5)
# print(rsp) # 4.0
# 其他
# 1. setbit
# ===========================================================
# setbit(name, offset, value):对name对应值的二进制表示的位进行操作
# offset必须为整型,value必须为0 or 1
# 每次返回上次的value
# ===========================================================
# if is_connected:
# rsp = rs.setbit(name='name', offset='6', value='1')
# print(rs.get(name='name'))
# 2. getbit
# =========================================================
# getbit(name, offset):获取name对应的二进制位表示的值,只能是0或1
# =========================================================
# getbit(name, offset)
# if is_connected:
# rsp = rs.getbit(name='name', offset=4)
# print(rsp)
rs.close()