class SignedFileRequest(SignedRequest):
def __init__(self, host, path, node_id = None, name=None, \
content_type=None, hash=None, ssl=False, expires=0):
super(SignedFileRequest, self).__init__(host, path, ssl, expires)
self.name = name
self.content_type = content_type
self.hash = hash
self.node_id = node_id
def get_name(self):
return self.query_dict.get(NAME_KEY)
def set_name(self, value):
self.query_dict[NAME_KEY] = value
def get_content_type(self):
return self.query_dict.get(CONTENT_TYPE_KEY)
def set_content_type(self, value):
self.query_dict[CONTENT_TYPE_KEY] = value
def get_hash(self):
return self.query_dict.get(HASH_KEY)
def set_hash(self, value):
self.query_dict[HASH_KEY] = value
def get_node_id(self):
return self.query_dict.get(NODE_ID_KEY)
def set_node_id(self, value):
self.query_dict[NODE_ID_KEY] = value
name = property(get_name, set_name)
content_type = property(get_content_type, set_content_type)
hash = property(get_hash, set_hash)
node_id = property(get_node_id, set_node_id)
Asked
Active
Viewed 156 times
-1

Alexandre
- 5,035
- 7
- 29
- 36
-
And what would the pattern be? Please provide more detail as to how you'd expect to map attribute to `query_dict` key, for example. – Martijn Pieters Sep 26 '12 at 10:04
-
possible duplicate of [Can anyone help condense this Python code?](http://stackoverflow.com/questions/11921320/can-anyone-help-condense-this-python-code) – Jon Clements Sep 26 '12 at 10:10
2 Answers
2
You could use a class decorator:
def keyprop(keymap):
def decorator(cls):
for name, key in keymap.items():
def getter(self):
return self.query_dict.get(NAME_KEY)
def setter(self, value):
self.query_dict[NAME_KEY] = value
setattr(cls, name, property(getter, setter))
return decorator
keymap = {'name' : NAME_KEY,
'content_type' : CONTENT_TYPE_KEY,
'hash' : HASH_KEY,
'node_id' : NODE_ID_KEY}
@keyprop(keymap)
class SignedFileRequest(SignedRequest):
def __init__(self, host, path, node_id = None, name=None, \
content_type=None, hash=None, ssl=False, expires=0):
super(SignedFileRequest, self).__init__(host, path, ssl, expires)
self.name = name
self.content_type = content_type
self.hash = hash
self.node_id = node_id

unutbu
- 842,883
- 184
- 1,785
- 1,677
-
Very nice answer, and you answered first. I think Martijn's answer is a little bit for complete. Do you mind if I award him the answer? – Alexandre Sep 27 '12 at 07:11
-
1
You could use the __getattr__
and __setattr__
hooks instead of a meta class:
class SignedFileRequest(SignedRequest):
__attr_map = dict(name=NAME_KEY, content_type=CONTENT_TYPE_KEY,
hash=HASH_KEY, node_id=NODE_ID_KEY)
def __init__(self, host, path, node_id = None, name=None, \
content_type=None, hash=None, ssl=False, expires=0):
super(SignedFileRequest, self).__init__(host, path, ssl, expires)
self.name = name
self.content_type = content_type
self.hash = hash
self.node_id = node_id
def __getattr__(self, attr):
if attr in self.__attr_map:
return self.query_dict.get(self.__attr_map[attr])
return super(SignedFileRequest, self).__getattr__(attr)
def __setattr__(self, attr, value):
if attr in self.__attr_map:
self.query_dict[self.__attr_map[attr]] = value
super(SignedFileRequest, self).__setattr__(attr, value)
Alternatively, the same mapping can be used to create a class decorator:
def add_property(klass, name, key):
def getter(self):
return self.query_dict.get(key)
def setter(self, value):
self.query_dict[key] = value
setattr(klass, name, property(getter, setter))
def set_properties(**mapping):
def decorator(klass):
for name, key in mapping.iteritems():
add_property(klass, name, key)
return klass
return decorator
@set_properties(name=NAME_KEY, content_type=CONTENT_TYPE_KEY,
hash=HASH_KEY, node_id=NODE_ID_KEY)
class SignedFileRequest(SignedRequest):
def __init__(self, host, path, node_id = None, name=None, \
content_type=None, hash=None, ssl=False, expires=0):
super(SignedFileRequest, self).__init__(host, path, ssl, expires)
self.name = name
self.content_type = content_type
self.hash = hash
self.node_id = node_id
Or you could go with a meta class approach anyway:
def mapped_properties_meta(**mapping):
def mapped_meta(name, bases, attrs):
klass = type(name, bases, attrs)
for name, key in mapping.iteritems():
add_property(klass, name, key)
return klass
return mapped_meta
class SignedFileRequest(SignedRequest):
__metaclass__ = mapped_properties_meta(
name=NAME_KEY, content_type=CONTENT_TYPE_KEY,
hash=HASH_KEY, node_id=NODE_ID_KEY)
def __init__(self, host, path, node_id = None, name=None, \
content_type=None, hash=None, ssl=False, expires=0):
super(SignedFileRequest, self).__init__(host, path, ssl, expires)
self.name = name
self.content_type = content_type
self.hash = hash
self.node_id = node_id
The latter reuses the add_property
function from the decorator approach.

Martijn Pieters
- 1,048,767
- 296
- 4,058
- 3,343