Python3中redis模块学习之string数据类型操作

起步

#!/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):设置值,过期时间为毫秒

说明:

关键字传参并不是必须的,可以位置传参,我只是习惯用关键字形式

示例:

  1. 设置一个名为 redis:method:set1,值为 setsstring key

    等价的redis命令:set redis:method:set 'sets'

    rsp = rs.set(name='redis:method:set', value='sets')
    
    print(rsp)  # True,表示当前set操作执行成功
    
  2. 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已经存在了
    
  3. 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已存在,符合条件
    
  4. setnx 没有设置过期时间的参数,只能结合 expire 方法

    等价的redis命令:setnx redis:method:setnx 'seetnx'

    rsp = rs.setnx(name='redis:method:setnx', value='setnx')
    
    print(rsp)
    
  5. 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
    
  6. 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对应的二进制位表示的值,只能是01

示例:

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()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值