Be Careful With Default Values for Method Parameters in Python

Today I Learned: python instantiates default values for method parameters only once — at method definition time. This can cause big problems if your method modifies values in these entities, because these modifications will be propagated to subsequent calls to the same method.

I spent the greater part of day yesterday hunting down some weird behavior in a python app, and I thought I'd share. Here is a simplified version* of what I found...

def test_method(self, http=httplib2.Http()):

   # Remember the original request method
   request_orig = http.request

   # Define a closure that executes the original request method
   def new_request():
      resp, content = request_orig()

   # Replace the request method with our own closure.
   http.request = new_request

We're assigning the new_request closure to the http.request method, and never resetting it. A subsequent method call sees this closure as the original method, and everything breaks down.

The fix is to remove the default http value, and always pass in a throwaway http object.

*Note: the real (more complicated version) is in the authorize() method (line 439) here.



Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

This question is for testing whether you are a human visitor and to prevent automated spam submissions.