摘要:原文地址近期在項(xiàng)目中使用到了相比較為齊全的工具這個(gè)非關(guān)系型數(shù)據(jù)庫客戶端只能通過與服務(wù)器端進(jìn)行交互于是有了為這個(gè)數(shù)據(jù)編寫個(gè)簡便的客戶端工具的想法。如果用戶沒有傳入對應(yīng)的參數(shù)則使用默認(rèn)的參數(shù)進(jìn)行綁定。
原文地址:
http://52sox.com/use-python-write-a-memcached-cli/
近期在項(xiàng)目中使用到了Memcached,相比redis較為齊全的工具,這個(gè)非關(guān)系型數(shù)據(jù)庫客戶端只能通過telnet與服務(wù)器端進(jìn)行交互,于是有了為這個(gè)數(shù)據(jù)編寫1個(gè)簡便的客戶端工具的想法。
如果你使用過redis提供的redis-cli,你會(huì)發(fā)現(xiàn)這個(gè)工具是多么的方便,比如某個(gè)命令你忘記了其使用的方式,你可以通過如下的方式來查看:
127.0.0.1:6379> help get GET key summary: Get the value of a key since: 1.0.0 group: string目標(biāo)
于是,打算參考redis-cli編寫1個(gè)Memcached的CLI,在這個(gè)版本中,我們要實(shí)現(xiàn):
輸入正確命令和參數(shù)后立即返回對應(yīng)的結(jié)果
1個(gè)提示幫助命令的功能
實(shí)現(xiàn)思路為了實(shí)現(xiàn)這個(gè)命令行版本,我們需要考慮以下幾個(gè)方面:
支持修改連接服務(wù)器的監(jiān)聽地址和端口
對傳入的參數(shù)進(jìn)行解析并調(diào)用對應(yīng)的方法
調(diào)用對應(yīng)命令并傳入?yún)?shù)后,如果參數(shù)不對能給出錯(cuò)誤的提示
支持幫助選項(xiàng)
對于第1個(gè)問題,我們可以通過參數(shù)的方式來解決。如果用戶沒有傳入對應(yīng)的參數(shù),則使用默認(rèn)的參數(shù)進(jìn)行綁定。關(guān)于從命令行中解析參數(shù)的方式,Python提供了幾種方式,這里我選用的是argparse模塊來操作。
而對應(yīng)后面3個(gè)問題,我們可以借助標(biāo)準(zhǔn)庫中的cmd模塊來實(shí)現(xiàn)。
在Python的Memcached的客戶端實(shí)現(xiàn)中,有python-memcached、pymemcache以及pylibmc等多種第3方庫,這里我采用的是pymemcache來說明我們這個(gè)命令行的實(shí)現(xiàn),主要原因在于它是純python實(shí)現(xiàn)中最快和異常處理比較好的1個(gè)庫。
實(shí)現(xiàn)下面,我們正式開始實(shí)現(xiàn)這個(gè)命令行。由于我們一般不會(huì)直接實(shí)例化Cmd類。我們先定義1個(gè)MemcachedCLI類,這個(gè)類繼承自cmd模塊中的Cmd類。接著,我們會(huì)實(shí)例化1個(gè)Memcached類的實(shí)例。
from pymemcache.client.base import Client from cmd import Cmd class MemcachedCLI(Cmd): def __init__(self, host, port): self.client = Client((host, port))
之后,我們需要對用戶輸入的內(nèi)容進(jìn)行解析并調(diào)用其對應(yīng)的方法。這方面,cmd模塊已經(jīng)幫助處理這方面的內(nèi)容了,我們只需要在該類中實(shí)現(xiàn)1個(gè)do_*的方法,當(dāng)我們在命令中輸入的1個(gè)對應(yīng)的命令時(shí),比如hello,其將調(diào)用1個(gè)do_hello的方法。
我們知道,在Memcached中有多個(gè)命令,如果我們對這些命令1個(gè)個(gè)的實(shí)現(xiàn),不是1件容易的事情。比如,在memcached中有1個(gè)get方法用于獲取指定鍵名的數(shù)值,而在pymemcache的實(shí)現(xiàn)中,Client實(shí)例有1個(gè)get方法對應(yīng)上述的這個(gè)指令。
因此,在這里,我們采用動(dòng)態(tài)獲取屬性的方式來簡化的工作量,即通過如下的方式來調(diào)用對應(yīng)的get方法:
getattr(self.client,"get")
我們將這個(gè)屬性的處理過程封裝在1個(gè)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類實(shí)例的每個(gè)屬性,如果對應(yīng)的屬性不以_字符開頭,我們則獲取該屬性,如果該屬性可以調(diào)用,我們再進(jìn)行屬性的設(shè)置,將其設(shè)置為該類的do_*屬性,通過該類_make_cmd方法返回對應(yīng)的數(shù)值。
在這里,我們將生成的cmd命令封裝在_make_cmd中,在這里我們將通過name屬性獲取到用戶在命令行中輸入的第1個(gè)參數(shù):
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
在這里我們需要對傳入的字符串進(jìn)行切分。比如,用戶輸入了set name 20,那么后面2個(gè)參數(shù)將以字符串name 20的形式傳入。之后,我們嘗試獲取Client類的該屬性,并傳入解包后的參數(shù)進(jìn)行調(diào)用。如果傳入的參數(shù)不正確,將觸發(fā)1個(gè)異常而被捕獲,并直接輸出。最后,我們返回1個(gè)handler函數(shù)。
這樣,當(dāng)我們輸入如下的命令時(shí):
set name 20
這將調(diào)用Client實(shí)例的set方法,并將name和20以參數(shù)的形式傳入,從而實(shí)現(xiàn)設(shè)置對應(yīng)鍵名及其鍵值。
這樣,我們就完成了我們前3個(gè)思路的工作。關(guān)于命令幫助的問題,在Python中存在1個(gè)docstring的東西,我們可以直接使用該類每個(gè)方法的__doc__屬性來實(shí)現(xiàn)對其文檔的獲取。而在cmd中提供了help_*的方法來實(shí)現(xiàn)對某個(gè)命令幫助文檔的調(diào)用。
而在pymemcache庫中這方面已經(jīng)幫助我們做好了,因此我們可以直接使用,我們只需要在之前的get_action方法中添加這么幾行代碼:
doc = (getattr(attr, "__doc__", "") or "").strip() if doc: setattr(self.__class__, "help_" + name, self._make_help(doc))
我們將其進(jìn)行判斷得到的對應(yīng)文檔是否為空字符串,如果不是才設(shè)置其對應(yīng)的方法。我將幫助文檔的內(nèi)容封裝在了1個(gè)_make_help的方法中:
def _make_help(self, doc): def help(self): print(doc) return help
在這里,我們直接輸出文檔的內(nèi)容即可。
總結(jié)最后,我們來看實(shí)際的效果,首先是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
然后是獲取某個(gè)指令的說明:
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.
最后是獲取和設(shè)置對應(yīng)的鍵值:
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
由于時(shí)間的限制,有一些細(xì)節(jié)的功能就不一一實(shí)現(xiàn)了。最后,可以通過如下的方式安裝使用:
pip install memcached-cli
參考文章:
https://pymemcache.readthedocs.io/en/latest/apidoc/modules.html
https://tghw.com/blog/cheeky-python-a-redis-cli
https://docs.python.org/2/library/cmd.html#module-cmd
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/61708.html
摘要:原文地址近期在項(xiàng)目中使用到了相比較為齊全的工具這個(gè)非關(guān)系型數(shù)據(jù)庫客戶端只能通過與服務(wù)器端進(jìn)行交互于是有了為這個(gè)數(shù)據(jù)編寫個(gè)簡便的客戶端工具的想法。如果用戶沒有傳入對應(yīng)的參數(shù)則使用默認(rèn)的參數(shù)進(jìn)行綁定。 原文地址: http://52sox.com/use-python-write-a-memcached-cli/ 近期在項(xiàng)目中使用到了Memcached,相比redis較為齊全的工具,這個(gè)非...
前言 在若干次前的一場面試,面試官看我做過python爬蟲/后端 的工作,順帶問了我些后端相關(guān)的問題:你覺得什么是后端? 送命題。當(dāng)時(shí)腦瓦特了,答曰:邏輯處理和數(shù)據(jù)增刪改查。。。 showImg(https://user-gold-cdn.xitu.io/2019/4/24/16a4ed4fc8c18078); 當(dāng)場被懟得體無完膚,羞愧難當(dāng)。事后再反思這問題,結(jié)合資料總結(jié)了一下。發(fā)現(xiàn)自己學(xué)過的Re...
摘要:安裝前準(zhǔn)備修改默認(rèn)主機(jī)名稱安裝依賴庫刪除系統(tǒng)默認(rèn)數(shù)據(jù)庫配置文件查詢刪除確認(rèn)卸載系統(tǒng)自帶查詢刪除安裝數(shù)據(jù)庫下載安裝包解壓創(chuàng)建數(shù)據(jù)庫安裝目錄,數(shù)據(jù)存放目錄, 安裝前準(zhǔn)備 修改默認(rèn)主機(jī)名稱 [root@iZuf60c5bxd15kr9gycvv6Z ~]# hostnamectl set-hostname centos [root@iZuf60c5bxd15kr9gycvv6Z ~]# re...
閱讀 3274·2023-04-25 18:03
閱讀 1143·2021-11-15 11:38
閱讀 5522·2021-10-25 09:45
閱讀 840·2021-09-24 09:48
閱讀 2272·2021-09-22 15:34
閱讀 1734·2019-08-30 15:44
閱讀 2675·2019-08-30 13:12
閱讀 604·2019-08-29 16:05