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