2019独角兽企业重金招聘Python工程师标准>>>

Memcached Python Client

本小菜刚学完python,想写点小东西练练手,然后看到memcached这个东东熟悉了下,感觉自己还能实现一点基本的功能(对于memcached这种分布式靠客户端来实现的神器,一些最重要的功能我都是还没有实现的。。。这个。。。),于是写了如下拙劣的代码,请各位大牛拍砖。。。

#!/usr/bin/env python'''
This is a fake memcached client.Overview
========
Cachedog use python native socket APIs to access memcached server.
It is inspired by python-memcached. This stuff is aim to be familiar
with Python language, for the author is a beginner for python.Commands
========
Standard Protocol:command <key> <flags> <expiration time> <bytes><value>The "standard protocol stuff" of memcached involves running a command against an "item".
An item consists of:1. A key (arbitrary string up to 250 bytes in length. No space or newlines for ASCII mode)
2. A 32bit "flag" value
3. An expiration time, in seconds. Can be up to 30 days. After 30 days, is treated as a unixtimestamp of an exact date.
4. A 64bit "CAS" value, which is kept unique.
5. Arbitrary dataCAS is optional (can be disabled entirely with -C, and there are more fields that internally
make up an item, but these are what your client interacts with.Full command list can be found here: https://code.google.com/p/memcached/wiki/NewCommandsUsage summary
=============
You must know it... :)TODO
====
add compress
add log
add multi-serversRelease note
============
0.1.0
Can access ONLY one server
Basic memcached command supported
Can log command history
'''
import os
import sys
import time
import socket
import logging# try:
#   import cPickle as pickle
# except ImportError:
#   import pickle#from binascii import crc32# try:
#     from threading import local
# except ImportError:
#     class local():
#         pass__author__ = 'xishvai <xishvai@gmail.com>'
__version__ = '0.1.0'
__license__ = 'Python Software Foundation License'SERVER_MAX_KEY_LENGTH = 250  # ordinary value
# assume not larger than 1M, you can change it as you need.
SERVER_MAX_VALUE_LENGTH = 1024 * 1024MAX_DATA_LENGTH = 1024 * 1024LOCALHOST = '127.0.0.1'
DEFAULT_PORT = 11211
DEFAULT_ADDRESS = (LOCALHOST, DEFAULT_PORT)class Noreply:passclass Client:def __init__(self, url):self.url = urlself.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)self.cmdlog = []self.cmd = Nonetry:a_url, a_port = self.url.split(':')addr = (a_url, int(a_port))self.sock.connect(addr)except socket.error, msg:print('Connecting %s error' % msg[1])sys.exit(1)## constants & exception & tools#_FLAG_INTEGER = 1 << 0_FLAG_LONG = 1 << 1_FLAG_PICKLE = 1 << 2_FLAG_COMPRESS = 1 << 3class MemcachedKeyError(Exception):passclass MemcachedKeyNoneError(MemcachedKeyError):passclass MemcachedKeyTypeError(MemcachedKeyError):passclass MemcachedKeyLengthError(MemcachedKeyError):passclass MemcachedKeyCharacterError(MemcachedKeyError):passclass MemcachedStringEncodingError(MemcachedKeyError):pass## Storage Commands: (set,add,replace,append,prepend,cas)#def set(self, key, value, flags=0, expired=0):'''Most common command. Store this data, possibly overwriting any existing data.New items are at the top of the LRU.'''self.cmd = '%s %s %d %d %d\r\n%s\r\n' % ('set', key, flags, expired, len(value), value)self.cmdlog.append(self.cmd)self.sock.sendall(self.cmd.encode())data = self.sock.recv(MAX_DATA_LENGTH)return datadef add(self, key, value, flags=0, expired=0):'''Store this data, only if it does not already exist. New items are at the top ofthe LRU. If an item already exists and an add fails, it promotes the item to thefront of the LRU anyway.'''self.cmd = '%s %s %d %d %d\r\n%s\r\n' % ('add', key, flags, expired, len(value), value)self.cmdlog.append(self.cmd)self.sock.sendall(self.cmd.encode())data = self.sock.recv(MAX_DATA_LENGTH)return datadef replace(self, key, value, flags=0, expired=0):'''Store this data, but only if the data already exists. Almost never used,and exists for protocol completeness (set, add, replace, etc)'''self.cmd = '%s %s %d %d %d\r\n%s\r\n' % ('replace', key, flags, expired, len(value), value)self.cmdlog.append(self.cmd)self.sock.sendall(self.cmd.encode())data = self.sock.recv(MAX_DATA_LENGTH)return datadef append(self, key, value, flags=0, expired=0):'''Add this data after the last byte in an existing item. This does not allowyou to extend past the item limit. Useful for managing lists.'''self.cmd = '%s %s %d %d %d\r\n%s\r\n' % ('append', key, flags, expired, len(value), value)self.cmdlog.append(self.cmd)self.sock.sendall(self.cmd.encode())data = self.sock.recv(MAX_DATA_LENGTH)return datadef prepend(self, key, value, flsgs=0, expired=0):'''Same as append, but adding new data before existing data.'''self.cmd = '%s %s %d %d %d\r\n%s\r\n' % ('prepend', key, flags, expired, len(value), value)self.cmdlog.append(self.cmd)self.sock.sendall(self.cmd.encode())data = self.sock.recv(MAX_DATA_LENGTH)return datadef cas(self, key, value, flags=0, expired=0, cas_value=0):'''Check And Set (or Compare And Swap). An operation that stores data, but only ifno one else has updated the data since you read it last. Useful for resolving raceconditions on updating cache data.'''self.cmd = '%s %s %d %d %d %d\r\n%s\r\n' % ('cas', key, flags, expired, cas_value, len(value), value)self.cmdlog.append(self.cmd)self.sock.sendall(self.cmd.encode())data = self.sock.recv(MAX_DATA_LENGTH)return data## Retrieval Commands: (get,gets,delete,incr/decr)#def get(self, key):'''Command for retrieving data. Takes one or more keys and returns all found items.'''self.cmd = '%s %s\r\n' % ('get', key)self.cmdlog.append(self.cmd)self.sock.sendall(self.cmd.encode())data = self.sock.recv(MAX_DATA_LENGTH)return datadef gets(self,key):'''An alternative get command for using with CAS. Returns a CAS identifier(a unique 64bit number) with the item. Return this value with the cas command.If the item's CAS value has changed since you gets'ed it, it will not be stored.'''self.cmd = '%s %s\r\n' % ('gets', key)self.cmdlog.append(self.cmd)self.sock.sendall(self.cmd.encode())data = self.sock.recv(MAX_DATA_LENGTH)return data        def delete(self, key):'''Removes an item from the cache, if it exists.'''self.cmd = '%s %s\r\n' % ('delete', key)self.cmdlog.append(self.cmd)self.sock.sendall(self.cmd.encode())data = self.sock.recv(MAX_DATA_LENGTH)return datadef incr(self, key):'''Increment and Decrement. If an item stored is the string representation of a 64bitinteger, you may run incr or decr commands to modify that number. You may only incrby positive values, or decr by positive values. They does not accept negative values.If a value does not already exist, incr/decr will fail.'''passdef decr(self, key):'''Increment and Decrement. If an item stored is the string representation of a 64bitinteger, you may run incr or decr commands to modify that number. You may only incrby positive values, or decr by positive values. They does not accept negative values.If a value does not already exist, incr/decr will fail.'''pass## Statistics: (stats,stats items,stats slabs,stats sizes,flush_all)#def stats(self):'''ye 'ole basic stats command.'''self.cmd = '%s\r\n' % 'stats'self.cmdlog.append(self.cmd)self.sock.sendall(self.cmd.encode())data = self.sock.recv(MAX_DATA_LENGTH)return datadef stats_items(self):'''Returns some information, broken down by slab, about items stored in memcached.'''self.cmd = '%s\r\n' % 'stats items'self.cmdlog.append(self.cmd)self.sock.sendall(self.cmd.encode())data = self.sock.recv(MAX_DATA_LENGTH)return datadef stats_slabs(self):'''Returns more information, broken down by slab, about items stored in memcached.More centered to performance of a slab rather than counts of particular items.'''self.cmd = '%s\r\n' % 'stats slabs'self.cmdlog.append(self.cmd)self.sock.sendall(self.cmd.encode())data = self.sock.recv(MAX_DATA_LENGTH)return datadef stats_sizes(self):'''A special command that shows you how items would be distributed if slabs were brokeninto 32byte buckets instead of your current number of slabs. Useful for determininghow efficient your slab sizing is.WARNING this is a development command. As of 1.4 it is still the only command whichwill lock your memcached instance for some time. If you have many millions of storeditems, it can become unresponsive for several minutes. Run this at your own risk. Itis roadmapped to either make this feature optional or at least speed it up.'''self.cmd = '%s\r\n' % 'stats sizes'self.cmdlog.append(self.cmd)self.sock.sendall(self.cmd.encode())data = self.sock.recv(MAX_DATA_LENGTH)return datadef flush_all(self):# flush_all([timeout])# lazy delete'''Invalidate all existing cache items. Optionally takes a parameter, which means to invalidateall items after N seconds have passed.This command does not pause the server, as it returns immediately. It does not free up orflush memory at all, it just causes all items to expire.'''self.cmd = '%s\r\n' % 'flush_all'self.cmdlog.append(self.cmd)self.sock.sendall(self.cmd.encode())data = self.sock.recv(MAX_DATA_LENGTH)return datadef stats_reset(self):pass# stats cachedump slab_id limit_numif __name__ == '__main__':mc = Client('127.0.0.1:11211')mc.set('xs', 'xishvai')mc.set('yj', 'yangjun')data = mc.get('xs')print('get xs = ', data)data1 = mc.get('yj')print('get yj = ', data1)mc.replace('yj', 'youngsmart')print('get yj = ', mc.get('yj'))mc.add('xs', 'xishvai')  # NOT_STOREDmc.delete('yj')mc.get('yj')mc.flush_all()print('get xs = ', mc.get('xs'))# for s in mc.cmdlog:#     print(s, ' ')# print('stats = ', mc.stats())# print('stats items= ', mc.stats_items())# print('stats slabs= ', mc.stats_slabs())# print('stats sizes= ', mc.stats_sizes())

啥也不说了,头上血迹斑斑啊。。。

转载于:https://my.oschina.net/xishvaigo/blog/180377

memcached python客户端编写实践相关推荐

  1. Python应用与实践【转】

    转自:http://www.cnblogs.com/skynet/archive/2013/05/06/3063245.html 目录 1.      Python是什么? 1.1.      Pyt ...

  2. 《偶像爱豆出身的编程语言排行第一得主!谁还敢嘲python没实力?》Python应用与实践

    可能有些标题党,没有针对某些具体的应用与实践.有哪些补充.不足请大家指出. Python是什么? Life is short, You need python 生命苦短,我用Python 1.1. P ...

  3. Python应用与实践

    1.      Python是什么? 1.1.      Python语言 1.2.      Python哲学 2.      Python在工作中的应用 2.1.      实例1:文件批量处理 ...

  4. Python应用与实践-转自(吴秦(Tyler))

    1.      Python是什么? 1.1.      Python语言 1.2.      Python哲学 2.      Python在工作中的应用 2.1.      实例1:文件批量处理 ...

  5. python使用spark_如何在Python中编写简单代码,并且速度超越Spark?

    全文共3482字,预计学习时长7分钟 如今,大家都在Python工具(pandas和Scikit-learn)的简洁性.Spark和Hadoop的可扩展性以及Kubernetes的操作就绪之间做选择. ...

  6. python 字节流分段_如何在Python中编写简单代码,并且速度超越Spark?

    全文共 3482字,预计学习时长 7分钟 如今,大家都在Python工具(pandas和Scikit-learn)的简洁性.Spark和Hadoop的可扩展性以及Kubernetes的操作就绪之间做选 ...

  7. 【2020新书】Python Pro专业实践原则,Practices of the Python Pro,250页pdf

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 转自:专知 Manning2020新书<Practices of the Pyt ...

  8. python如何导入txt数据集-终于找到python入门到实践数据集

    Python是一款功能强大的脚本语言,具有丰富和强大的库,重要的是,它还具有很强的可读性,易用易学,非常适合编程初学者入门.以下是小编为你整理的python入门到实践数据集 环境配置:下载Python ...

  9. 如何使用Python Flask编写Web服务

    我们的许多客户正在使用我们的Webhook功能来构建有用的服务,但不幸的是,其他客户却没有. 我们经常听到他们的团队中没有人足够熟练地编写一种服务,该服务可以提取Webhook负载并处理数据. 这使得 ...

最新文章

  1. opencv resize (C/C++/Python)
  2. Hive 数仓中常见的日期转换操作
  3. 推荐3款 Docker 认证的实用免费插件,帮助您快速构建云原生应用程序!
  4. java与数据结构(4)---java实现双向循环链表
  5. php分页样式,thinkphp分页样式修改
  6. 吴恩达《机器学习》第十二章:支持向量机SVM
  7. 导出已安装的插件_明明flash插件已安装,但是网页依然不能正常显示的解决办法...
  8. mysql 执行顺序_MySQL 基础知识掌握
  9. 一文读懂PID控制算法(抛弃公式,从原理上真正理解PID控制)
  10. 数控编程加工中心注意事项有哪些,你知道吗
  11. java找不到符号或方法,java 找不到符号解决方法
  12. 洛谷P1179 [NOIP2010 普及组] 数字统计题解
  13. 微信Mars-xlog日志加密踩坑指南
  14. echarts学习笔记1
  15. PCI8524 并行8Ch24Bits100Ksps高精度数据采集卡
  16. 【秘鲁收款】秘鲁外贸收款Pago Efectivo支付
  17. strcmp和strncmp函数
  18. 中国地址英文翻译,英文网站注册
  19. 旧金山大学 计算机,旧金山大学
  20. 电商数仓(dwd 层)

热门文章

  1. c# 第9节 数据类型之引用类型
  2. Linux内存buffer和cache的区别
  3. 组策略 从入门到精通 (一) 组策略的还原与备份和汇入
  4. Git基础之(二十)——标签管理——创建标签
  5. 四个常用的Java连接池
  6. (ios实战):retain,copy,assign及autorelease ,strong,weak
  7. ASP.NET系统 + Access数据库
  8. C++对象的内存分析(5)
  9. ASP.NET2.0中的ClientScriptManager 类用法—如何添加客户端事件
  10. jsp mysql 注入攻击实例