[Tutor] assign all parameters of __init__ to class variables?
Steven D'Aprano
steve at pearwood.info
Wed Nov 2 23:00:36 CET 2011
On Thu, 3 Nov 2011 12:57:25 am Alex Hall wrote:
> Thanks to both of you, that will work. I can see the argument for
> assigning everything manually, but I have each parameter on its own
> line with a comment to explain what it does, and I know I want all
> parameters to be class-level for every instantiation, so saying
> "self.[varName]=[varName]" twenty times seems like a waste of time
> and space.
Wait, you you want the parameters to be *class level*, that is, shared
by all instances? But you want them to be set each time you
instantiate an instance? That's fairly unusual. Normally people want
each instance to get its own instance-level attributes.
In Python, one way of doing this would be:
class K(object):
a = 1 # class-level shared attribute defined once only
def __init__(self, b):
self.__class__.b = b # Set the shared class-level attribute
And in action:
>>> ham = K(23)
>>> ham.a, ham.b
(1, 23)
>>> eggs = K(42)
>>> ham.a, ham.b
(1, 42)
Notice that you must assign the attribute on the class object itself,
not the instance. So if you have a bunch of parameters, rather than
updating the instance dictionary, you have to update the class
dictionary. (This makes error checking and parameter validation even
more important, because you can screw your class up by overwriting
methods if you pass the wrong parameter name.)
But assuming you like living dangerously, or you trust the caller not
to be stupid:
class K(object):
a = 1
def __init__(self, **kwargs):
self.__class__.__dict__.update(kwargs)
But having done that, it still won't really work the way you expect
(or at least the way I *think* you will expect). The problem is that
the instance still has its own dict, so when the caller assigns to an
attribute:
instance = K(b=2, c=3)
instance.d = 4
b and c become class-level, as requested, but d is instance-level and
any other instances will not share that value.
The best way to ensure all instances share the same attributes is with
the Borg design pattern:
http://code.activestate.com/recipes/66531/
(Also known as Monostate, or the poorly-named "stateless proxy".)
The above recipe is for classic classes, which no longer exist in
Python 3; for a new-style class version, see the comment by Alex
Naanou on that page. The other alleged new-style Borgs actually
implement Singletons.
But if the difference between a Singleton and a Borg matters to you,
you're probably up to no good. <wink>
--
Steven D'Aprano
More information about the Tutor
mailing list