How to set object parameters nicely?
Bruno Desthuilliers
bruno.42.desthuilliers at websiteburo.invalid
Thu Dec 3 11:22:20 EST 2009
allen.fowler a écrit :
(snip)
> In this case, and I am trying to create a number of ORM-like objects.
> (Though, there is no database involved.)
>
> So, instances of these classes are acting as records that are shuttled
> around in the system, and the object's properties are acting as
> values. The parameters are (mostly) orthogonal, but do need defaults,
> and some must be required.
You could specify the names, defaults and validations required at an
upper level then automate the whole thing, ie (thinking out loud):
class Field(object):
def __init__(self, name,required=False,
default=None,target=None,validate=None):
self._name = name
self._required = required
self._default = default
self._target = target or name
self._validate = validate or lambda x: x
def validate(self, value):
""" _validate is supposed to raise a ValueError if not ok.
it can also do any required conversion, formatting etc
"""
return self._validate(value)
def set(self, instance, **kw):
value = kw.get(self._name, None)
if value is None
if self.required:
raise ValueError("argument %s is required" % self._name)
else:
value = self._default
value = self.validate(value)
setattr(instance, self._target, value)
class Record(object):
def __init__(self, **kw):
if not hasattr(self, "_fields"):
raise AttributeError("Record subclasses must define _fields")
for field in self._fields:
field.set(self, **kw)
class Foo(Record):
_fields = (
Field("bar", True, validate=lambda v : v > 1),
Field("baaz", default=42)
)
NB : totally untested code, so it will of course contains at least one
major and obvious bug / typo / whatever !-)
You could go further using an even more declarative API based on a fancy
custom metaclass and descriptors (for Fields) etc etc - and that even
might be the RightThing(tm) to do if you have more than moderatly
complex needs, but for simple cases the above should work fine without
going over the top with black magic.
HTH
More information about the Python-list
mailing list