patternpythonMinor
Python class w/ Telnet interface to memcached
Viewed 0 times
memcachedinterfacepythontelnetclass
Problem
I haven't had anyone help me out with code review, etc, so I thought I'd post a Python class I put together for interfacing with Telnet to get information from a memcached server.
This is also up on GitHub.
I would love some feedback on:
import re, telnetlib
class MemcachedStats:
_client = None
def __init__(self, host='localhost', port='11211'):
self._host = host
self._port = port
@property
def client(self):
if self._client is None:
self._client = telnetlib.Telnet(self._host, self._port)
return self._client
def key_details(self, sort=True):
' Return a list of tuples containing keys and details '
keys = []
slab_ids = self.slab_ids()
for id in slab_ids:
self.client.write("stats cachedump %s 100\n" % id)
response = self.client.read_until('END')
keys.extend(re.findall('ITEM (.*) \[(.*); (.*)\]', response))
if sort:
return sorted(keys)
return keys
def keys(self, sort=True):
' Return a list of keys in use '
return [key[0] for key in self.key_details(sort=sort)]
def slab_ids(self):
' Return a list of slab ids in use '
self.client.write("stats items\n")
response = self.client.read_until('END')
return re.findall('STAT items:(.*):number', response)
def stats(self):
' Return a dict containing memcached stats '
self.client.write("stats\n")
response = self.client.read_until('END')
return dict(re.findall("STAT (.*) (.*)\r", response))This is also up on GitHub.
I would love some feedback on:
- Organization
- Better ways of accomplishing the same result
Solution
The pattern
appears three times in your code. I think this is often enough to warrant refactoring it into its own method like this:
In
Afterwards you do this:
Now this might be a matter of opinion, but I'd rather write this using an
I think this is optically more pleasing as both
self.client.write("some command\n")
response = self.client.read_until('END')appears three times in your code. I think this is often enough to warrant refactoring it into its own method like this:
def command(self, cmd):
self.client.write("%s\n" % cmd)
return self.client.read_until('END')In
key_details you're using extend to build up a list. However it's more pythonic to use list comprehensions than building up a list imperatively. Thus I'd recommend using the following list comprehension:regex = 'ITEM (.*) \[(.*); (.*)\]'
cmd = "stats cachedump %s 100"
keys = [key for id in slab_ids for key in re.findall(regex, command(cmd % id))]Afterwards you do this:
if sort:
return sorted(keys)
return keysNow this might be a matter of opinion, but I'd rather write this using an
else:if sort:
return sorted(keys)
else:
return keysI think this is optically more pleasing as both
returns are indented at the same level. It also makes it immediately obviously that the second return is what happens if the if condition is false.Code Snippets
self.client.write("some command\n")
response = self.client.read_until('END')def command(self, cmd):
self.client.write("%s\n" % cmd)
return self.client.read_until('END')regex = 'ITEM (.*) \[(.*); (.*)\]'
cmd = "stats cachedump %s 100"
keys = [key for id in slab_ids for key in re.findall(regex, command(cmd % id))]if sort:
return sorted(keys)
return keysif sort:
return sorted(keys)
else:
return keysContext
StackExchange Code Review Q#636, answer score: 7
Revisions (0)
No revisions yet.