39

I was wondering if anyone had any good ways of quickly explaining how to efficiently and pythonically create user defined objects with optional arguments. For instance, I want to create this object:

class Object:
    def __init__(self, some_other_object, i, *j, *k):
        self.some_other_object = some_other_object
        self.i = i
        # If j is specified, assume it is = i
        if(j==None):
            self.j = i
        else:
            self.j = j
        # If k is given, assume 0
        if(k==None):
            self.k = 0
        else:
            self.k = k

Is there a better way to do this?

3
  • 2
    This isn't valid, you can't have multiple * arguments. The argument prefixed with a * becomes a list of all non-keyword arguments that come after that point. Commented Mar 20, 2013 at 22:12
  • Thanks @Lattyware , that helps. I saw the *args and *keywordsargs, etc. and thought they may have been referring to different arguments passed. Commented Mar 20, 2013 at 22:17
  • toxotes's answer is what you want, it just has one major flaw (see my comment on it). Commented Mar 20, 2013 at 22:17

2 Answers 2

64

You can set default parameters:

class OpticalTransition(object):
    def __init__(self, chemical, i, j=None, k=0):
        self.chemical = chemical
        self.i = i
        self.k = k
        self.j = j if j is not None else i

If you don't explicitly call the class with j and k, your instance will use the defaults you defined in the init parameters. So when you create an instance of this object, you can use all four parameters as normal: OpticalTransition('sodium', 5, 100, 27)

Or you can omit the parameters with defaults with OpticalTransition('sodium', 5), which would be interpreted as OpticalTransition('sodium', 5, None, 0)

You can use some default values but not all of them as well, by referencing the name of the parameter: OpticalTransition('sodium', 5, k=27) uses j's default but not k's.

Python won't allow you to do j=i as a default parameter (i isn't an existing object that the class definition can see), so the self.j line handles this with an if statement that in effect does the same thing.

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

8 Comments

Generally, by the way, don't bother with if x == None, just do if x. is bad advice. Many values can evaluate to False - if you want to check for None, do if x is None:, not if x:. In this example, if j is 0, it will do something unexpected. -1, until this is fixed.
You're right -- I was thinking the OP was doing that to see if it existed at all, not necessarily to see if they had the value of None.
Thanks @toxotes , this makes sense and looks very simple.
@Lattyware Shouldn't it be 'if j is not None:'? since it is already 'None' by default?
@chase Good catch, fixed - it was actually a little more complicated a fault than that, but should be good now. I felt the ternary operator is a good choice here.
|
5

I am too new to stackoverflow to up-vote or comment, but I approve of ronak's answer. Gareth Latty's comment about default parameters is addressed by using the [default] option of the get method.

dictionary.get(key[, default])

using **args allows for less/ more readable code when there are many optional variables to be passed. It is simply passing passing dictionary key-value pairs as parameters.

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.