[Python-ideas] Simple class initialization
Adam Matan
adam at matan.name
Sat Apr 16 14:14:00 CEST 2011
I think that this solution damages the __init__() signature because the
caller does
not know which arguments should be passed. Furthermore, it is quite long,
and does
not allow introspection.
On Sat, Apr 16, 2011 at 3:08 PM, dag.odenhall at gmail.com <
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.
> > 1. Credit
> > =========
> > The idea emerged from my question at stackoverflow.com. I would like to
> > thank
> > all those who answered and commented on that thread.
> > http://stackoverflow.com/questions/1389180
> > 2. The problem
> > ==============
> > Consider the following class:
> > class Process:
> > def __init__(self, pid, ppid, cmd, fd, reachable, user):
> > If the instance needs to hold these arguments internally, local data
> > attributes
> > are declared and the value of the argument is being copied, using two
> > mainstream
> > notations:
> > a.
> > self.pid=pid
> > self.ppid=ppid
> > self.cmd=cmd
> > self._fd=fd
> > self.reachable=reachable
> > self.user=user
> > b.
> > self.pid, self.ppid, self.cmd, self._fd, self.reachable,
> > self.user = pid, ppid, cmd, fd, reachable, user
> > a. takes an unreasonable amount of lines and has a repetative form.
> > b. is long and prone to errors, especially when the argument list changes
> > during development.
> > 3. Solution outline
> > ===================
> > 1. Generally comply with the Zen of Python.
> > 1. Explicit. The instance should not store any value unless told.
> > 2. Short.
> > 3. Backward compatible. Current Class syntax should work with the
> > new solution.
> > 4. Readable and intuitive.
> > 5. Flexible. There should be a way to store any given subset of
> > the arguments.
> > 6. Allow storage of "private" variables by adding a single or double
> > underscore before the variable name.
> > 4. Solutions
> > ============
> > 4.1 Decorator
> > -------------
> > Nadia Alramli suggested this at the aforementiond thread at
> stackoverflow:
> > from functools import wraps
> > import inspect
> > def initializer(fun):
> > names, varargs, keywords, defaults = inspect.getargspec(fun)
> > @wraps(fun)
> > def wrapper(self, *args):
> > for name, arg in zip(names[1:], args):
> > setattr(self, name, arg)
> > fun(self, *args)
> > return wrapper
> > class Process:
> > @initializer
> > def __init__(self, pid, ppid, cmd, fd, reachable, user)
> > Pros:
> > Simple, short, explicit and intuitive.
> > Easy to add to the standard library, fully backward-compatible.
> > Cons:
> > Stores all arguments.
> > Does not support private data attributes notation (underscore
> prefix).
> > See
> >
> http://stackoverflow.com/questions/1389180/python-automatically-initialize-instance-variables/1389216#1389216
> >
> > 4.2. Argument tagging
> > ---------------------
> > Arguments that needed to be stored within the instance could be marked
> with
> > a
> > special character, e.g. '~'. The character would be placed after the
> > argument
> > name for private variables:
> > class Process:
> > def __init__(self, ~pid, ~ppid, ~cmd, fd~, ~reachable, ~user)
> > Pros:
> > Simple, short and explicit.
> > Can store any subset of the arguments.
> > Supports private variable notation.
> > Cons:
> > Not intuitive. Changes the method signature and might be confusing.
> >
> > 4.3 Standard function
> > ---------------------
> > A function will be called to store the argument as data attributes.
> > class Process:
> > def __init__(self, pid, ppid, cmd, fd, reachable, user)
> > acquire(pid, ppid, cmd, reachable, user)
> > acquire(fd, prefix='_')
> > Possible keywords can ba acquire, store, absorp.
> > Pros:
> > Explicit, clear and intuitive.
> > Cons:
> > Long - especially if more than a single prefix is used.
> > 4.4 Initialization list
> > -----------------------
> > The argument list would include the name of the local data attribute, a
> > separator, and the argument name.
> > class Process:
> > def __init__(self, pid:pid, ppid:ppid, cmd:cmd, _fd:fd,
> > reachable:reachable, user:user)
> > """ pid, ppid, cmd, reachable and user are stored as data
> > properties
> > with the same name. fd is stored as _fd."""
> > Or:
> > class Process:
> > def __init__(self, :pid, :ppid, :cmd, _fd:fd, :reachable,
> :user)
> > """Same, but local data attributes with the same name as
> > arguments
> > would be stored without stating their name twice."""
> > This is a developed argument tagging (4.2).
> > Pros:
> > See 4.2
> > Cons:
> > Alters the method signature
> > Not intuitive.
> >
> > Looking forward for comments,
> > Adam matan
>
>
> class Process:
>
> # Defaults and documentation as class attributes
> pid = None
>
> def __init__(self, **kwargs):
> for k, v in kwargs.iteritems():
> setattr(self, k, v)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20110416/48b22394/attachment.html>
More information about the Python-ideas
mailing list