5

I have this code:

def __init__(self, a, b, c, d...):
   self.a = a
   self.b = b
   etc

I'm thinking of replacing it with:

def __init__(self, a, b, c, d...):
   args=locals()
   for key in args:
     self.__dict__[key] = args[key]

Is this a bad idea? Are there any better ways to do this?

4
  • 1
    Might want to be careful about the self argument, but otherwise looks OK Commented Jun 11, 2012 at 1:43
  • Will the number of inputs change, or is there a set number? Commented Jun 11, 2012 at 1:43
  • Thanks Ixop, The number of input will not change. Commented Jun 11, 2012 at 1:51
  • 2
    Can you explain what you hope to accomplish with this change? Commented Jun 11, 2012 at 1:58

4 Answers 4

9

From the Zen of Python: Simple is better than complex. and Readability counts.

The explicit assignments are much more readable and simpler than using magic to set the values.

Sign up to request clarification or add additional context in comments.

2 Comments

The thing is there are approximately 20 such variables; is explicit assignment still better? and by explicit assignment, you mean "self.a = a", etc?
A method accepting 20 variables sounds bad. HAve you considered accepting **kwargs and doing self.__dict__.update(kwargs)?
2

Building on @ThiefMaster's comment about **kwargs:

If you are taking in 20 arguments, it might make more sense to require your users to send arguments via keyword instead of position: with 20 arguments, there is a decent chance that someone using your code will get the arguments in the wrong order.

Consider only accepting kwargs while having a predefined list of keys you want to accept and raising a ValueError if you don't receive them. So you could use **kwargs and then check that everything is there. E.g.

INITIAL_ARGS = set(['a','b','c','d','e'...])

def __init__(self, **kwargs):
    if not INITIAL_ARGS.issubset(set(kwargs.iterkeys())):
        raise ValueError("Class <myclass> requires 20 keyword arguments"
                          "only given %d" % len(kwargs))
    self.__dict__.update(kwargs)

Not sure whether this is more or less Pythonic than your original, but it seems like it would save a ton of time later on when trying to figure out why someone using your code might be getting strange errors.

1 Comment

If the OP expects the same number of args in every call (that was said in a comment), I'd go with == rather than issubset - don't want the user to add other random keyword arguments that don't do anything but pollute the namespace!
1

Always consider readability over clever design. Is the replacement code easier to read? I would probably just leave it. Remember that simple is better than complex. As the ThiefMaster said, the explicit assignments are more readable.

Comments

0

Another alternative for Python3 users: the init decorator from drastic.

@init
def __init__(self, a, b, c, d, e, f, g, h):
    # nothing to write here!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.