473,569 Members | 2,555 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Default attribute values pattern

A situation that often comes up is having to initialize several
instance attributes that accept a default value. For a single class,
passing the default values in __init__ is fine:

class Base(object):
def __init__(self, x=0, y=None):
self.x = x
self.y = y

For inherited classes that need to override __init__ while keeping a
compatible interface though, the default values have to be repeated:

class Derived(Base):
def __init__(self, x=0, y=None, z=''):
super(Derived,s elf).__init__(s elf,x,y)
self.z = ''

For just two attributes and two classes that's maybe not too bad but
for many attributes and/or derived classes that may span multiple
modules, that doesn't seem to scale from a maintenance point of view,
especially if the defaults change over time.

A pattern I've been using lately instead is store the defaults in
class attributes and let __init__ accept keyword arguments:

class Base(object):

x = 0
y = None

def __init__(self, **kwds):
setattrs(self, kwds)

where setattrs is:

def setattrs(self, attrvals, strict=True):
if strict:
# raise AttributeError if some attr doesn't exist already
for attr in attrvals.iterke ys():
getattr(self,at tr)
for attr,val in attrvals.iterit ems():
setattr(self, attr, val)

This way, only the new and overriden default attributes have to
repeated in derived classes:

class Derived(Base):

x = 1
z = ''

def __init__(self, **kwds):
super(Derived,s elf).__init__(* *kwds)
print 'In Derived.__init_ _'
Is this a good way of doing it ? Is there a better pattern ?

George
Jan 19 '08 #1
7 1436
Hello,

Seems to me that setattrs sort of assumes that you want to have all your
initialization arguments set as attributes of the same name. I would think
you'd sometimes want to be able to process the extra arguments inside of each
__init__, assign them to attributes with different names, etc.

My approach would be to treat each __init__ as a wrapping function, grabbing
the items it needs out of the keyword dictionary and then calling the next
__init__. Curious to hear other approaches though:
def Grab(argdict, key, default):
"""Like argdict.get(key , default), but also deletes key from argdict."""
if key in argdict:
retval = argdict["key"]
del(argdict[key])
else:
retval = default
return retval
class Base(object):
def __init__(self, x=0, y=None):
print "in Base init"
self.x = x
self.y = y
class Derived1(Base):
def __init__(self, **kwargs):
print "in Derived1 init"
self.z = Grab(kwargs, "z", None)
super(Derived1, self).__init__( **kwargs)
class Derived2(Derive d1):
def __init__(self, **kwargs):
print "in Derived2 init"
self.a = Grab(kwargs, "a", 0)
self.b = Grab(kwargs, "b", False)
super(Derived2, self).__init__( **kwargs)
print self.__dict__
newthing = Derived2(x=234, y="blah", a=55555)
On Jan 19, 2008 10:14 AM, George Sakkis <ge***********@ gmail.comwrote:
A situation that often comes up is having to initialize several
instance attributes that accept a default value. For a single class,
passing the default values in __init__ is fine:

class Base(object):
def __init__(self, x=0, y=None):
self.x = x
self.y = y

For inherited classes that need to override __init__ while keeping a
compatible interface though, the default values have to be repeated:

class Derived(Base):
def __init__(self, x=0, y=None, z=''):
super(Derived,s elf).__init__(s elf,x,y)
self.z = ''

For just two attributes and two classes that's maybe not too bad but
for many attributes and/or derived classes that may span multiple
modules, that doesn't seem to scale from a maintenance point of view,
especially if the defaults change over time.

A pattern I've been using lately instead is store the defaults in
class attributes and let __init__ accept keyword arguments:

class Base(object):

x = 0
y = None

def __init__(self, **kwds):
setattrs(self, kwds)

where setattrs is:

def setattrs(self, attrvals, strict=True):
if strict:
# raise AttributeError if some attr doesn't exist already
for attr in attrvals.iterke ys():
getattr(self,at tr)
for attr,val in attrvals.iterit ems():
setattr(self, attr, val)

This way, only the new and overriden default attributes have to
repeated in derived classes:

class Derived(Base):

x = 1
z = ''

def __init__(self, **kwds):
super(Derived,s elf).__init__(* *kwds)
print 'In Derived.__init_ _'
Is this a good way of doing it ? Is there a better pattern ?

George
--
http://mail.python.org/mailman/listinfo/python-list


--
-David
Jan 19 '08 #2
On Jan 19, 11:02*pm, "David Tweet" <davidtw...@gma il.comwrote:
def Grab(argdict, key, default):
* """Like argdict.get(key , default), but also deletes key from argdict."""
* if key in argdict:
* * retval = argdict["key"]
* * del(argdict[key])
* else:
* * retval = default
* return retval
Dictionaries already have a method for this. It's called pop. It's a
good idea to have a look at methods of builtin types before
reimplementing the wheel!

Grab(argdict, key, default) is argdict.pop(key , default)

--
Arnaud

Jan 20 '08 #3
Ah! nice, thanks, knew I was probably missing something.

On Jan 19, 2008 5:01 PM, Arnaud Delobelle <ar*****@google mail.comwrote:
On Jan 19, 11:02pm, "David Tweet" <davidtw...@gma il.comwrote:
def Grab(argdict, key, default):
"""Like argdict.get(key , default), but also deletes key from argdict."""
if key in argdict:
retval = argdict["key"]
del(argdict[key])
else:
retval = default
return retval

Dictionaries already have a method for this. It's called pop. It's a
good idea to have a look at methods of builtin types before
reimplementing the wheel!

Grab(argdict, key, default) is argdict.pop(key , default)

--
Arnaud
--
http://mail.python.org/mailman/listinfo/python-list


--
-David
Jan 20 '08 #4
David Tweet a écrit :
(<ot>please, don't top-post</ot>)
>
def Grab(argdict, key, default):
cf pep08 for naming conventions...
"""Like argdict.get(key , default), but also deletes key from argdict."""
if key in argdict:
retval = argdict["key"]
del(argdict[key])
else:
retval = default
return retval
def grab(kw, key, default=None):
try:
return kw.pop(key)
except KeyError:
return default

(snip)
Jan 21 '08 #5
Grab(argdict, key, default) is argdict.pop(key , default)

"pop() raises a KeyError when no default value is given and the key is
not found."
def grab(kw, key, default=None):
try:
return kw.pop(key)
except KeyError:
return default
So Bruno's technique seems to me to be the correct one as it catches
the KeyError.
Jan 21 '08 #6
On Jan 21, 10:09*am, cokofree...@gma il.com wrote:
Grab(argdict, key, default) is argdict.pop(key , default)

"pop() raises a KeyError when no default value is given and the key is
not found."
And it doesn't if a default is provided, which is always the case in
the uses of Grab(...), so it seems the right tool for the job.
def grab(kw, key, default=None):
* *try:
* * *return kw.pop(key)
* *except KeyError:
* * *return default

So Bruno's technique seems to me to be the correct one as it catches
the KeyError.
If you really really want to write a grab function (IMHO pop is good
enough):

def grab(kw, key, default=None):
return kw.pop(key, default)

--
Arnaud
Jan 21 '08 #7
co*********@gma il.com a écrit :
>Grab(argdict , key, default) is argdict.pop(key , default)

"pop() raises a KeyError when no default value is given and the key is
not found."
Then use it with a default value !-)
>def grab(kw, key, default=None):
try:
return kw.pop(key)
except KeyError:
return default

So Bruno's technique seems to me to be the correct one as it catches
the KeyError.
Note that I cancelled the message (too bad, doesn't work everywhere). I
totally agree with Arnaud on this, and should sometimes re-read the doc
for stuff I use so often I think I know them.
Jan 21 '08 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
1498
by: UndoMiel | last post by:
Hi, I have a situation where i would like to validate the occurance of certain elements, based on the value of an attribute. What is the "best" way to handle such validations? I am fairly new to XML and its validation techniques. Schematron would probably do the trick, but i havent found a straight forward way that solves my problem. ...
4
2924
by: Lénaïc Huard | last post by:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello, I've some namespace problems when defining default values for attributes. My problem seems to come from the fact that the attributes are defined in a different namespace from the element.
0
1240
by: pathisunil | last post by:
Dear All I have an xmldocument which is as formed below. It is a bit of loopy in nature. can anyone kindly let me know how can i write a xslt which would take a parameter which is an attribute value and would like to have details out of the xml file. I will the paste the xmldocument for your reference.The values required as output are...
2
3950
by: Bill Cohagan | last post by:
In my app I'm validating an XML file against an XSD which contains several attribute default value specifications. I'm performing the validation via an xml document load() using a ValidatingXMLReader. After loading the document (and validating it) I assume that the resulting doc will (as appropriate) have elements with attributes set to their...
12
4934
by: Stefano | last post by:
Hi all, what is the correct use of the "default" attribute in XML Schema? For example: <xs:element name="myProperty" type="xs:string" default="myDefaultValue"/> What can I do with it? What is the meaning of < ....default="myDefaultValue" /> ?
0
1172
by: pathisunil | last post by:
Dear All I have an xmldocument which is as formed below. It is a bit of loopy in nature. can anyone kindly let me know how can i write a xslt which would take a parameter which is an attribute value and would like to have details out of the xml file.
44
2727
by: gregory.petrosyan | last post by:
Hello everybody! I have little problem: class A: def __init__(self, n): self.data = n def f(self, x = ????) print x All I want is to make self.data the default argument for self.f(). (I
4
17257
by: Dave Burns | last post by:
Hello, I am trying to specify a logical default value for a in a WCF Web Service using basicHttpBinding. I realize that the language defaults are: int - 0 string - null bool - false
14
2811
by: Roedy Green | last post by:
Is there a shortcut way to define the default font family (and characteristics) to be applied to all styles? -- Roedy Green Canadian Mind Products The Java Glossary http://mindprod.com
0
7615
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7924
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8130
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
7979
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6284
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5514
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5219
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3653
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
1
2115
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.