variable & scoping question.

Discussion in 'Python' started by Cornelius Keller, Aug 10, 2009.

  1. Hi,

    I'm a quite fresh python programmer, (6 Month python experience).
    Today I found something I absolotly don'nt understand:

    given the following function:

    def test_effect(class_id=None,class_ids=[]):
    if class_id is not None:
    if class_id not in class_ids:
    class_ids.append(int(class_id))

    print class_ids

    I observe that the class_ids array is growing when it is called with
    different class id's.

    I expected class_ids to be [] if the keyword argument is not set, but
    it seems to beahve like a static variable if not set.

    example:


    In [3]: test.test_effect(class_id=1)
    [1]

    In [4]: test.test_effect(class_id=1)
    [1]

    In [5]: test.test_effect(class_id=2)
    [1, 2]

    In [6]: test.test_effect(class_id=2)
    [1, 2]

    In [7]: test.test_effect(class_id=3)
    [1, 2, 3]

    Is this an intended python beahviour?

    sincerly
    - Cornelius
     
    Cornelius Keller, Aug 10, 2009
    #1
    1. Advertising

  2. Cornelius Keller wrote:

    > Hi,
    >
    > I'm a quite fresh python programmer, (6 Month python experience).
    > Today I found something I absolotly don'nt understand:
    >
    > given the following function:
    >
    > def test_effect(class_id=None,class_ids=[]):
    >     if class_id is not None:
    >         if class_id not in class_ids:
    >             class_ids.append(int(class_id))
    >
    >     print class_ids
    >
    > I observe that the class_ids array is growing when it is called with
    > different class id's.
    >
    > I expected class_ids to be [] if the keyword argument is not set, but
    > it seems to beahve like a static variable if not set.


    http://effbot.org/zone/default-values.htm

    Diez
     
    Diez B. Roggisch, Aug 10, 2009
    #2
    1. Advertising

  3. On Aug 10, 5:12 pm, "Diez B. Roggisch" <> wrote:
    > Cornelius Keller wrote:
    > > Hi,

    >
    > > I'm a quite fresh python programmer, (6 Month python experience).
    > > Today I found something I absolotly don'nt understand:

    >
    > > given the following function:

    >
    > > def test_effect(class_id=None,class_ids=[]):
    > >     if class_id is not None:
    > >         if class_id not in class_ids:
    > >             class_ids.append(int(class_id))

    >
    > >     print class_ids

    >
    > > I observe that the class_ids array is growing when it is called with
    > > different class id's.

    >
    > > I expected class_ids to be [] if the keyword argument is not set, but
    > > it seems to beahve like a static variable if not set.

    >
    > http://effbot.org/zone/default-values.htm
    >
    > Diez


    Maybe on the first page of python.org there should be a 'python
    gotchas' link to a page listing these few
    non-intuituive peculiarities of our beloved snake ... same goes for
    the official python tutorial ...

    Ciao
    -----
    FB
     
    Francesco Bochicchio, Aug 10, 2009
    #3
  4. On 10 Aug., 17:12, "Diez B. Roggisch" <> wrote:
    > Cornelius Keller wrote:

    [snip]
    >
    > http://effbot.org/zone/default-values.htm
    >
    > Diez


    Ok thank you.
    I' understand now why.
    I still think this is very confusing, because default values don't
    behave like most people would expect without reading the docs.

    - Cornelius
     
    Cornelius Keller, Aug 10, 2009
    #4
  5. Cornelius Keller

    MRAB Guest

    Francesco Bochicchio wrote:
    > On Aug 10, 5:12 pm, "Diez B. Roggisch" <> wrote:
    >> Cornelius Keller wrote:
    >>> Hi,
    >>> I'm a quite fresh python programmer, (6 Month python experience).
    >>> Today I found something I absolotly don'nt understand:
    >>> given the following function:
    >>> def test_effect(class_id=None,class_ids=[]):
    >>> if class_id is not None:
    >>> if class_id not in class_ids:
    >>> class_ids.append(int(class_id))
    >>> print class_ids
    >>> I observe that the class_ids array is growing when it is called with
    >>> different class id's.
    >>> I expected class_ids to be [] if the keyword argument is not set, but
    >>> it seems to beahve like a static variable if not set.

    >> http://effbot.org/zone/default-values.htm
    >>
    >> Diez

    >
    > Maybe on the first page of python.org there should be a 'python
    > gotchas' link to a page listing these few
    > non-intuituive peculiarities of our beloved snake ... same goes for
    > the official python tutorial ...
    >

    Should they be called 'snake bites'? Well, pythons are constrictors, not
    biters, but if Python is being non-intuitive... :)
     
    MRAB, Aug 10, 2009
    #5
  6. Cornelius Keller

    Ethan Furman Guest

    Cornelius Keller wrote:
    [snip]

    > I still think this is very confusing, because default values don't
    > behave like most people would expect without reading the docs.
    >
    > - Cornelius


    Why would you expect to become a good programmer of _any_ language
    without reading its docs?

    ~Ethan~
     
    Ethan Furman, Aug 10, 2009
    #6
  7. On Mon, 10 Aug 2009 08:46:17 -0700 (PDT), Cornelius Keller
    <> declaimed the following in
    gmane.comp.python.general:

    >
    > Ok thank you.
    > I' understand now why.
    > I still think this is very confusing, because default values don't
    > behave like most people would expect without reading the docs.
    >

    They work as any Python object would... Given a single point of
    definition everything else is up to whether it is a mutable object or
    not...

    alist = [] #mutable
    avalue = 3.14159 #immutable

    def thing1():
    alist.append(2) #mutates outer scope
    avalue = 2 #local

    def thing2():
    global avalue
    alist = [ avalue ] #binding is to local
    avalue = 2 #rebinds outer scope

    def credenza(av, al):
    al.append(av) #mutates al
    av = 3 #acts as local

    credenza(avalue, alist)



    Default arguments are just an assignment statement to the object
    created during the parse/compile phase.
    --
    Wulfraed Dennis Lee Bieber KD6MOG
    HTTP://wlfraed.home.netcom.com/
     
    Dennis Lee Bieber, Aug 10, 2009
    #7
  8. On Mon, 2009-08-10 at 08:46 -0700, Cornelius Keller wrote:
    > On 10 Aug., 17:12, "Diez B. Roggisch" <> wrote:
    > > Cornelius Keller wrote:

    > [snip]
    > >
    > > http://effbot.org/zone/default-values.htm
    > >
    > > Diez

    >
    > Ok thank you.
    > I' understand now why.
    > I still think this is very confusing, because default values don't
    > behave like most people would expect without reading the docs.
    >
    > - Cornelius


    You are correct. This is confusing at first blush. The important thing
    to remember is: *don't do that.* Learn the pythonic workaround of using
    None in your parameters whenever you want a default empty list, and
    don't let it bother you too much. Overall, python is a remarkably well
    designed language. This is one of the relatively rare warts that crept
    in because it enables a broader cleanliness of design.

    Cheers,
    Cliff
     
    J. Cliff Dyer, Aug 10, 2009
    #8
  9. On Mon, 10 Aug 2009 08:46:17 -0700, Cornelius Keller wrote:

    > On 10 Aug., 17:12, "Diez B. Roggisch" <> wrote:
    >> Cornelius Keller wrote:

    > [snip]
    >>
    >> http://effbot.org/zone/default-values.htm
    >>
    >> Diez

    >
    > Ok thank you.
    > I' understand now why.
    > I still think this is very confusing, because default values don't
    > behave like most people would expect without reading the docs.



    Really? How do you expect the default value to behave in this example?

    >>> import time
    >>> def test(x=time.time()):

    .... print x
    ....
    >>>
    >>> test()

    1249972984.33
    >>> time.sleep(30)
    >>> test()

    1249972984.33

    You get the same default object each time you call the function, NOT a
    fresh one created. I'm sure I'd be terribly confused if Python re-
    evaluated the default value each time I called the function.

    There's no difference between this and the case x=[], except that lists
    are mutable and floats aren't. You get the same default list each time,
    it just has different stuff in it. The alternative would be to get a
    different list each time, and that would require re-evaluating the
    default each time the function was called, which is horrible.




    --
    Steven
     
    Steven D'Aprano, Aug 11, 2009
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. NevilleDNZ
    Replies:
    9
    Views:
    451
    NevilleDNZ
    Aug 16, 2006
  2. Replies:
    6
    Views:
    544
  3. Omari Norman
    Replies:
    5
    Views:
    279
    Tim Slattery
    Jun 25, 2008
  4. Linuxguy123
    Replies:
    1
    Views:
    246
  5. Brian Candler

    Variable scoping

    Brian Candler, Sep 10, 2004, in forum: Ruby
    Replies:
    4
    Views:
    123
    Brian Candler
    Sep 10, 2004
Loading...

Share This Page