[Python-ideas] Simple class initialization
Chris Rebert
pyideas at rebertia.com
Sun Apr 17 00:53:50 CEST 2011
On Sat, Apr 16, 2011 at 4:50 AM, 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.
<snip>
> 4. Solutions
> ============
> 4.1 Decorator
> -------------
<snip>
> class Process:
> @initializer
> def __init__(self, pid, ppid, cmd, fd, reachable, user):
<snip>
> 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.
You could easily combine 4.1 and 4.2 by using function annotations
(PEP 3107 - http://www.python.org/dev/peps/pep-3107/ ); this would
eliminate the need to add any new syntax. Example:
from wherever import initializer, Private as Priv, Public as Pub
class Process:
@initializer
def __init__(self, pid: Pub, ppid: Pub, cmd: Pub, fd: Priv,
reachable: Pub, user: Pub):
> 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.
-1; I strongly disagree. This function would have to be rather magical
since `self` isn't passed to it; it would have to mess with call stack
frames to grab `self` from the caller's scope. I'm unsure whether that
would be resilient in the face of methods which name `self` something
else (e.g. `s`), and whether that would be easily portable to
non-CPython implementations.
> 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).
Again, I think function annotations would be a better approach here. Example:
class Process:
@initializer
def __init__(self, pid: 'pid', ppid: 'ppid', cmd: 'cmd', fd:
'_fd', reachable: 'reachable', user: 'user'):
or allowing for more implicitness:
class Process:
@initializer
def __init__(self, pid, ppid, cmd, fd: '_fd', reachable, user):
Cheers,
Chris
--
http://blog.rebertia.com
More information about the Python-ideas
mailing list