Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Instance Variable as Default Parameter [duplicate]

Tags:

python

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?

like image 803
DuneBug Avatar asked May 14 '10 00:05

DuneBug


3 Answers

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.

like image 96
Michael Aaron Safyan Avatar answered Nov 02 '22 01:11

Michael Aaron Safyan


A common way is to use None as the default value

def _writeAndWait (self, string, timeout=None):
    if timeout is None:
        timeout = self._timeout
like image 29
John La Rooy Avatar answered Nov 02 '22 00:11

John La Rooy


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
like image 38
tinu Avatar answered Nov 02 '22 01:11

tinu