[Python-ideas] Simple class initialization
Nathan Schneider
nathan at cmu.edu
Sat Apr 16 19:23:13 CEST 2011
I like the initializer decorator. Here's a version that (1) handles keyword
argument defaults, and (2) allows only a subset of arguments to be stored
via decorator arguments:
def initializer(*selectedArgs):
def wrap(fun):
names, varargs, varkwargs, defaults = inspect.getargspec(fun)
@wraps(fun)
def wrapper(self, *args, **kwargs):
d = dict(zip(names[-len(defaults):],defaults))
d.update(dict(zip(names[1:], args)))
d.update(kwargs)
for a in (selectedArgs if len(selectedArgs)>0 else d.keys()):
assert a in names,'Invalid parameter name: {}'.format(a)
assert a in d,'Missing required argument: {}'.format(a)
setattr(self, a, d[a])
fun(self, *args, **kwargs)
return wrapper
return wrap
class Process1:
@initializer()
def __init__(self, pid, ppid, cmd, fd, reachable=True, user=None)
class Process2:
@initializer('pid','ppid','user') # only store these 3; self.cmd will
trigger an error
def __init__(self, pid, ppid, cmd, fd, reachable=True, user=None)
Nathan
On Sat, Apr 16, 2011 at 12:25 PM, Ethan Furman <ethan at stoneleaf.us> wrote:
> dag.odenhall at gmail.com wrote:
>>
>> On 16 April 2011 13:50, Adam Matan <adam at matan.name> wrote:
>>>
>>> 0. Abstract
>>> ===========
>>> A class initialization often begins with a long list of explicit
variable
>>> declaration statements at the __init__() method. This repetitively
copies
>>> arguments into local data attributes.
>>> This article suggests some semi-automatic techniques to shorten and
>>> clarify
>>> this code section. Comments and responses are highly appreciated.
>
> [snippers]
>
>> class Process:
>>
>> # Defaults and documentation as class attributes
>> pid = None
>>
>> def __init__(self, **kwargs):
>> for k, v in kwargs.iteritems():
>> setattr(self, k, v)
>
> I like the initialiser function myself:
>
> 8<-------------------------------------------------------------
> def acquire(obj, kwargs):
> Missing = object()
> for kw, val in kwargs.items():
> name = '_'+kw
> attr = getattr(obj, name, Missing)
> if attr is Missing:
> name = kw
> attr = getattr(obj, name, Missing)
> if attr is not Missing:
> setattr(obj, name, val)
>
> class Process:
> pid = None
> ppid = None
> cmd = None
> reachable = None
> user = None
> _fd = None
> def __init__(self, pid, ppid, cmd, fd, reachable, user):
> acquire(self, locals())
> print(self.pid)
> print(self.ppid)
> print(self.cmd)
> print(self.reachable)
> print(self.user)
> print(self._fd)
>
> if __name__ == '__main__':
> p = Process(9, 101, 'cd /', 0, 'yes', 'root')
> 8<-------------------------------------------------------------
>
> Don't think it needs to be in the stdlib, though.
>
> ~Ethan~
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20110416/9c1cd101/attachment.html>
More information about the Python-ideas
mailing list