15

I have am writing a Python function that takes a timeout value as a parameter. Normally, the user will always use the same timeout value, but on occasion he may want to wait slightly longer. The timeout value is stored as a class instance variable. I want to use the class' timeout instance variable as the default parameter. Currently, I am implementing this as follows:

def _writeAndWait (self, string, timeout = -1):
    if (timeout == -1):
        timeout = self._timeout

I was just wondering, is the proper way to use an instance variable as a default parameter? Or is there a better way that would avoid the "if" check?

jonrsharpe
  • 99,167
  • 19
  • 183
  • 334
DuneBug
  • 1,483
  • 4
  • 15
  • 28

3 Answers3

18

The short answer to your question is no, you cannot eliminate the if statement, because Python examines the signature only once, and so the default is shared across all calls. Consider, for example:

def addit(x, L=[]):
    L.append(x)
    return L

Versus:

def addit(x,L=None):
     if L is None:
         L=[]
     L.append(x)
     return L

These two functions, though they look identical, actually have completely different behavior; in the first one, the default value of L is shared between invocations so that addit(1) followed by addit(2) will return, in the first case, two objects that are actually point to the same underlying object and that have a value of [1,2], while it the second case it will return two separate objects, [1] and [2].

The only recommendation I have for you, then, is to use a default of None simply because that is the standard convention for parameters that have not been specified, but to continue using an if check, because using as a default value some existing object will have subtly different (usually wrong) behavior.

Michael Aaron Safyan
  • 87,518
  • 14
  • 130
  • 194
17

A common way is to use None as the default value

def _writeAndWait (self, string, timeout=None):
    if timeout is None:
        timeout = self._timeout
John La Rooy
  • 263,347
  • 47
  • 334
  • 476
1

In python >2.5 you can safe one line by using the ternary condition operator:

def _writeAndWait (self, string, timeout=None):
    timeout = self._timeout if timeout is None else timeout
Community
  • 1
  • 1
tinu
  • 11
  • 2