Why don't optional mutable objects show up in vars(func)?

Discussion in 'Python' started by dannycolligan@gmail.com, Sep 27, 2006.

  1. Guest

    So I just got bitten by the "don't use a mutable object as an optional
    argument" gotcha. I now realize that for this function:

    >>> def func(x, y=[]):

    .... y.append(x)
    .... print y
    ....

    y is initialized when the function is imported, not when the function
    is executed. However, if this is the case, then why is y not showing
    up as an attribute of func?

    >>> vars(func)

    {}
    >>> dir(func)

    ['__call__', '__class__', '__delattr__', '__dict__', '__doc__',
    '__get__', '__getattribute__', '__hash__', '__init__', '__module__',
    '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
    '__setattr__', '__str__', 'func_closure', 'func_code', 'func_defaults',
    'func_dict', 'func_doc', 'func_globals', 'func_name']

    I'm using Python 2.4.3, if that is at all relevant. Thanks in advance
    for any help.

    Danny
     
    , Sep 27, 2006
    #1
    1. Advertising

  2. Georg Brandl Guest

    wrote:
    > So I just got bitten by the "don't use a mutable object as an optional
    > argument" gotcha. I now realize that for this function:
    >
    >>>> def func(x, y=[]):

    > ... y.append(x)
    > ... print y
    > ...
    >
    > y is initialized when the function is imported, not when the function
    > is executed. However, if this is the case, then why is y not showing
    > up as an attribute of func?
    >
    >>>> vars(func)

    > {}
    >>>> dir(func)

    > ['__call__', '__class__', '__delattr__', '__dict__', '__doc__',
    > '__get__', '__getattribute__', '__hash__', '__init__', '__module__',
    > '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
    > '__setattr__', '__str__', 'func_closure', 'func_code', 'func_defaults',
    > 'func_dict', 'func_doc', 'func_globals', 'func_name']
    >
    > I'm using Python 2.4.3, if that is at all relevant. Thanks in advance
    > for any help.


    y is not an attribute of func, it's a default parameter value and as such
    stored in func_defaults:

    >>> def f(x=1):

    .... pass
    ....
    >>> print f.func_defaults

    (1,)
    >>>


    Georg
     
    Georg Brandl, Sep 27, 2006
    #2
    1. Advertising

  3. wrote:

    > So I just got bitten by the "don't use a mutable object as an optional
    > argument" gotcha. I now realize that for this function:
    >
    >>>> def func(x, y=[]):

    > ... y.append(x)
    > ... print y
    > ...
    >
    > y is initialized when the function is imported, not when the function
    > is executed. However, if this is the case, then why is y not showing
    > up as an attribute of func?


    >>> func.func_defaults

    ([],)

    </F>
     
    Fredrik Lundh, Sep 27, 2006
    #3
  4. schrieb:
    > So I just got bitten by the "don't use a mutable object as an optional
    > argument" gotcha. I now realize that for this function:
    >
    >>>> def func(x, y=[]):

    > ... y.append(x)
    > ... print y
    > ...
    >
    > y is initialized when the function is imported, not when the function
    > is executed. However, if this is the case, then why is y not showing
    > up as an attribute of func?


    Because it's not an attribute of the function object; it's a default
    value of the function.

    >>>> vars(func)

    > {}
    >>>> dir(func)

    > ['__call__', '__class__', '__delattr__', '__dict__', '__doc__',
    > '__get__', '__getattribute__', '__hash__', '__init__', '__module__',
    > '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
    > '__setattr__', '__str__', 'func_closure', 'func_code', 'func_defaults',
    > 'func_dict', 'func_doc', 'func_globals', 'func_name']
    >
    > I'm using Python 2.4.3, if that is at all relevant. Thanks in advance
    > for any help.


    Take a look at func_defaults.

    Regards,
    Martin
     
    =?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=, Sep 27, 2006
    #4
  5. Sean Hammond Guest

    On Wed, 2006-09-27 at 09:32 -0700, wrote:
    > So I just got bitten by the "don't use a mutable object as an optional
    > argument" gotcha. I now realize that for this function:
    >
    > >>> def func(x, y=[]):

    > ... y.append(x)
    > ... print y
    > ...
    >
    > y is initialized when the function is imported, not when the function
    > is executed.


    I thought it was initialised the first time the function gets called?
     
    Sean Hammond, Sep 27, 2006
    #5
  6. Sean Hammond wrote:

    >>>>> def func(x, y=[]):

    >> ... y.append(x)
    >> ... print y
    >> ...
    >>
    >> y is initialized when the function is imported, not when the function
    >> is executed.

    >
    > I thought it was initialised the first time the function gets called?


    it's initialized (in the surrounding context) when the "def" statement
    is executed.

    </F>
     
    Fredrik Lundh, Sep 27, 2006
    #6
    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. CRON
    Replies:
    24
    Views:
    203,696
    Adrienne Boswell
    Jun 20, 2006
  2. Johnny
    Replies:
    3
    Views:
    482
    Robert Kern
    Aug 23, 2005
  3. Hari Sekhon
    Replies:
    0
    Views:
    555
    Hari Sekhon
    Jun 20, 2006
  4. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,214
    Smokey Grindel
    Dec 2, 2006
  5. Vinko Vrsalovic

    int func() v/s int func(void)

    Vinko Vrsalovic, Jan 21, 2005, in forum: C Programming
    Replies:
    14
    Views:
    1,372
    Villy Kruse
    Jan 24, 2005
Loading...

Share This Page