1

AFAIK, Python evaluates the defaults of a function only once, at declaration time. So calling the following function printRandom

import random
def printRandom(randomNumber = random.randint(0, 10)):
    print randomNumber

will print the same number each time called without arguments. Is there a way to force reevaluation of the default randomNumber at each function call without doing it manually? Below is what I mean by "manually":

import random
def printRandom(randomNumber):
    if not randomNumber:
         randomNumber = random.randint(0, 10)
    print randomNumber
Randomblue
  • 112,777
  • 145
  • 353
  • 547

3 Answers3

6

No. The default arguments are set when they are executed, which is when the function is defined. If you wanted them to be re-executed, you would need to re-define the function.

The standard idiom, and the one you should use, is

import random
def print_random(random_number=None):
    if random_number is None:
        random_number = 4 # chosen by fair dice roll.
                          # guaranteed to be random.
    print random_number

Note the use of None (a singleton) and the is test for object identity. You shouldn't use if not random_number since there are many values which evaluate to boolean false -- in particular, 0.

There are plenty of other ways you could do this, but there's no reason not to follow the convention.

Katriel
  • 120,462
  • 19
  • 136
  • 170
  • Thanks! What is the difference between `random_number == None` and `random_number is None`? – Randomblue Jan 17 '12 at 13:50
  • He already said that in his answer but well: `is` is the test for object _identity_, while `==` checks two objects for _equality_. `1.0 is 1 == False` while `(1.0 == 1) == True`. – Gandaro Jan 17 '12 at 13:55
  • That's a [common question](http://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is-in-python) :p. In short, `==` tests whether the objects are _semantically equal_ (i.e. hold the same data), and `is` tests whether they are _the same object_. In comparing to `None` you should use `is`; this is one of the few cases where you should do so :p. – Katriel Jan 17 '12 at 13:56
  • You will probably never see a difference in your code between `==None` and `is None`, but it is possible: a class which overrides `__eq__` might compare equal to `None` (see [this blog post](http://jaredgrubb.blogspot.com/2009/04/python-is-none-vs-none.html)). But in general you should use `is` here because PEP 8 says to. – Katriel Jan 17 '12 at 13:58
3

Use None:

def printRandom(randomNumber=None):
    if randomNumber is None:
        randomNumber = random.randint(0, 10)
    print randomNumber
detly
  • 29,332
  • 18
  • 93
  • 152
2

I think the best bet would be to define None as default value for randomNumber.

def printRandom(randomNumber=None):
    if randomNumber is None:
        print random.randint(0, 10)
    else:
        print randomNumber
Gandaro
  • 3,427
  • 1
  • 17
  • 19