0
回答
Python-编写1个Memcached 的命令行
终于搞明白,存储TCO原来是这样算的>>>   

近期在项目中使用到了Memcached,相比redis较为齐全的工具,这个非关系型数据库客户端只能通过telnet与服务器端进行交互,于是有了为这个数据编写1个简便的客户端工具的想法。

 

如果你使用过redis提供的redis-cli,你会发现这个工具是多么的方便,比如某个命令你忘记了其使用的方式,你可以通过如下的方式来查看:

 

127.0.0.1:6379> help get  

  

  GET key  

  summary: Get the value of a key  

  since: 1.0.0  

  group: string 

 

目标

 

于是,打算参考redis-cli编写1个Memcached的CLI,在这个版本中,我们要实现:

 

  • 输入正确命令和参数后立即返回对应的结果

  • 1个提示帮助命令的功能

 

实现思路

 

为了实现这个命令行版本,我们需要考虑以下几个方面:

 

  • 支持修改连接服务器的监听地址和端口

  • 对传入的参数进行解析并调用对应的方法

  • 调用对应命令并传入参数后,如果参数不对能给出错误的提示

  • 支持帮助选项

 

对于第1个问题,我们可以通过参数的方式来解决。如果用户没有传入对应的参数,则使用默认的参数进行绑定。关于从命令行中解析参数的方式,Python提供了几种方式,这里我选用的是argparse模块来操作。

而对应后面3个问题,我们可以借助标准库中的cmd模块来实现。

 

选择客户端绑定

 

在Python的Memcached的客户端实现中,有python-memcached、pymemcache以及pylibmc等多种第3方库,这里我采用的是pymemcache来说明我们这个命令行的实现,主要原因在于它是纯python实现中最快和异常处理比较好的1个库。

 

实现

 

下面,我们正式开始实现这个命令行。由于我们一般不会直接实例化Cmd类。我们先定义1个MemcachedCLI类,这个类继承自cmd模块中的Cmd类。接着,我们会实例化1个Memcached类的实例。

 

from pymemcache.client.base import Client  

from cmd import Cmd  

 

class MemcachedCLI(Cmd):  

    def __init__(self, host, port):  

        self.client = Client((host, port))

 

之后,我们需要对用户输入的内容进行解析并调用其对应的方法。这方面,cmd模块已经帮助处理这方面的内容了,我们只需要在该类中实现1个do_*的方法,当我们在命令中输入的1个对应的命令时,比如hello,其将调用1个do_hello的方法。

我们知道,在Memcached中有多个命令,如果我们对这些命令1个个的实现,不是1件容易的事情。比如,在memcached中有1个get方法用于获取指定键名的数值,而在pymemcache的实现中,Client实例有1个get方法对应上述的这个指令。

因此,在这里,我们采用动态获取属性的方式来简化的工作量,即通过如下的方式来调用对应的get方法:

 

getattr(self.client,'get')

 

我们将这个属性的处理过程封装在1个get_action的方法中:

 

def get_action(self, client):  

    for name in dir(client):  

        if not name.startswith('_'):  

            attr = getattr(client, name)  

            if callback(attr):  

                setattr(self.__class__, 'do_' + name, self._make_cmd(name))

 

在这里,我们遍历Client类实例的每个属性,如果对应的属性不以_字符开头,我们则获取该属性,如果该属性可以调用,我们再进行属性的设置,将其设置为该类的do_*属性,通过该类_make_cmd方法返回对应的数值。

在这里,我们将生成的cmd命令封装在_make_cmd中,在这里我们将通过name属性获取到用户在命令行中输入的第1个参数:

 

def _make_cmd(self, name):  

        def handler(self, line):  

            parts = line.split()  

            try:  

                print(getattr(self.client, name)( *parts))  

            except Exception as e:  

                print('Error:{0}'.format(e))  

        return handler

 

在这里我们需要对传入的字符串进行切分。比如,用户输入了set name 20,那么后面2个参数将以字符串name 20的形式传入。之后,我们尝试获取Client类的该属性,并传入解包后的参数进行调用。如果传入的参数不正确,将触发1个异常而被捕获,并直接输出。最后,我们返回1个handler函数。

这样,当我们输入如下的命令时:

 

set name 20

 

这将调用Client实例的set方法,并将name和20以参数的形式传入,从而实现设置对应键名及其键值。

 

这样,我们就完成了我们前3个思路的工作。关于命令帮助的问题,在Python中存在1个docstring的东西,我们可以直接使用该类每个方法的__doc__属性来实现对其文档的获取。而在cmd中提供了help_*的方法来实现对某个命令帮助文档的调用。

 

而在pymemcache库中这方面已经帮助我们做好了,因此我们可以直接使用,我们只需要在之前的get_action方法中添加这么几行代码:

 

doc = (getattr(attr, '__doc__', '') or '').strip()  

if doc:  

    setattr(self.__class__, 'help_' + name, self._make_help(doc))

 

我们将其进行判断得到的对应文档是否为空字符串,如果不是才设置其对应的方法。我将帮助文档的内容封装在了1个_make_help的方法中:

 

def _make_help(self, doc):  

        def help(self):  

            print(doc)  

        return help

 

在这里,我们直接输出文档的内容即可。

最后,我们来看实际的效果,首先是help列出所有可用的命令:

 

127.0.0.1:11211>help  

  

Documented commands (type help ):  

========================================  

EOF     check_key  delete_many   get        gets_many  quit      set_multi  

add     close      delete_multi  get_many   help       replace   stats      

append  decr       exit          get_multi  incr       set       touch      

cas     delete     flush_all     gets       prepend    set_many  version  

 

然后是获取某个指令的说明:

 

127.0.0.1:11211>help get  

  

The memcached "get" command, but only for one key, as a convenience.  

  

        Args:  

          key: str, see class docs for details.  

  

        Returns:  

          The value for the key, or None if the key wasn't found.

 

最后是获取和设置对应的键值:

 

127.0.0.1:11211>get name  

None  

127.0.0.1:11211>set name zhangsan  

True  

127.0.0.1:11211>get name  

zhangsan  

 

由于时间的限制,有一些细节的功能就不一一实现了。最后,可以通过如下的方式安装使用:

 

pip install memcached-cli

选择自己学习方法
   每个人都有适合自己的方法,有的人去选择自学,有的人选择看视频学习,有的人选择报名培训班,那在这个时候,你就要自己考虑清楚,到底那样对的帮助是最大的,个人觉得是跟着培训班最好的,毕竟人家的实战项目多,我们学软件开发的都知道实战项目对于学好一门语言是 很重要的。

学习python有那些误区

具体里面的误区非常的多,那些就不需要我去写出来,我给你说的一般都是心态的问题,首先一个觉得自己会java和c++,然后我学习python就很牛,但是你要知道语言是有很多相同的地方,但是不是通用,一定要自己学习的仔细。还有一种就是觉得我不会英语,我要先去把英语学习好在来学python。因为自己想还坏主意然后学习,这样的都是容易找进误区的。

怎么样才能学好python学好python你需要一个良好的环境,一个优质的开发交流群,群里都是那种相互帮助的人才是可以的,我有建立一个python学习交流群,在群里我们相互帮助,相互关心,相互分享内容,这样出问题帮助你的人就比较多,群号是301,还有056,最后是051,这样就可以找到大神聚合的群,如果你只愿意别人帮助你,不愿意分享或者帮助别人,那就请不要加了,你把你会的告诉别人这是一种分享。如果你看了觉得还可以的麻烦给我点个赞谢谢
  

 

<无标签>
举报
铁扇公主1
发帖于6个月前 0回/34阅
顶部