How to reduce the DRY violation in this code
alister
alister.ware at ntlworld.com
Wed Sep 28 05:18:28 EDT 2016
On Wed, 28 Sep 2016 01:49:56 +1000, Steve D'Aprano wrote:
> I have a class that takes a bunch of optional arguments. They're all
> optional, with default values of various types. For simplicity, let's
> say some are ints and some are floats:
>
>
> class Spam:
> def __init__(self, bashful=10.0, doc=20.0, dopey=30.0,
> grumpy=40, happy=50, sleepy=60, sneezy=70):
> # the usual assign arguments to attributes dance... self.bashful
> = bashful self.doc = doc # etc.
>
>
> I also have an alternative constructor that will be called with string
> arguments. It converts the strings to the appropriate type, then calls
> the real constructor, which calls __init__. Again, I want the arguments
> to be optional, which means providing default values:
>
>
> @classmethod def from_strings(cls, bashful='10.0', doc='20.0',
> dopey='30.0',
> grumpy='40', happy='50', sleepy='60', sneezy='70'):
> bashful = float(bashful)
> doc = float(doc)
> dopey = float(dopey)
> grumpy = int(grumpy)
> happy = int(happy)
> sleepy = int(sleepy)
> sneezy = int(sneezy)
> return cls(bashful, doc, dopey, grumpy, happy, sleepy, sneezy)
>
>
> That's a pretty ugly DRY violation. Imagine that I change the default
> value for bashful from 10.0 to (let's say) 99. I have to touch the code
> in three places (to say nothing of unit tests):
>
This is often refered to as using "Magic Numbers" and can be avoided by
using constants
HAPPY='50'
SNEEZY='70'
<snip>
def spam:
def __init__(self,happy=HAPPY,sneezy=SNEEZY,...)
of course Python does not have true constants (hence following the PEP 8
recommendation of making them all caps) so you have to behave yourself
regarding their usage.
at least now they only need to be changed in 1 location.
that said when I find i have situations like this it is often a good idea
to re-investigate my approach to the overall problem to see if there is
another way to implement it.
--
"Humor is a drug which it's the fashion to abuse."
-- William Gilbert
More information about the Python-list
mailing list