Unbinding multiple variables

Discussion in 'Python' started by Johnny Lin, Jan 21, 2005.

  1. Johnny Lin

    Johnny Lin Guest

    Hi!

    Is there a way to automate the unbinding of multiple variables? Say I
    have a list of the names of all variables in the current scope via
    dir(). Is there a command using del or something like that that will
    iterate the list and unbind each of the variables?

    Thanks much! (If anyone posts an answer, if you could also cc your
    reply to my email , would be much obliged. Thanks
    again!)

    Best,
    -Johnny
    www.johnny-lin.com
     
    Johnny Lin, Jan 21, 2005
    #1
    1. Advertising

  2. Johnny Lin

    John Hunter Guest

    >>>>> "Johnny" == Johnny Lin <> writes:

    Johnny> Hi! Is there a way to automate the unbinding of multiple
    Johnny> variables? Say I have a list of the names of all
    Johnny> variables in the current scope via dir(). Is there a
    Johnny> command using del or something like that that will iterate
    Johnny> the list and unbind each of the variables?


    Hi Johnny

    I assume you are the one and only Johnny Lin at the U of C, no?

    John-Hunters-Computer:~> python
    Python 2.3 (#1, Sep 13 2003, 00:49:11)
    [GCC 3.3 20030304 (Apple Computer, Inc. build 1495)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> x = 1
    >>> y = 2
    >>> locals()

    {'__builtins__': <module '__builtin__' (built-in)>, '__name__':
    '__main__', 'y': 2, '__doc__': None, 'x': 1}
    >>> print x,y

    1 2
    >>> del locals()['x']
    >>> print x,y

    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    NameError: name 'x' is not defined
    >>> locals()

    {'__builtins__': <module '__builtin__' (built-in)>, '__name__':
    '__main__', 'y': 2, '__doc__': None}
    >>>
     
    John Hunter, Jan 21, 2005
    #2
    1. Advertising

  3. On 20 Jan 2005 19:24:43 -0800, Johnny Lin <> wrote:
    > Hi!
    >
    > Is there a way to automate the unbinding of multiple variables? Say I
    > have a list of the names of all variables in the current scope via
    > dir(). Is there a command using del or something like that that will
    > iterate the list and unbind each of the variables?
    >
    > Thanks much! (If anyone posts an answer, if you could also cc your
    > reply to my email , would be much obliged. Thanks
    > again!)


    My immediate reaction is "You never want to do that"

    If you're doing something along these lines:

    #some code
    #create lots of variables
    #do stuff with those variables
    # <want to delete variables here
    #more code

    Try converting it to this idiom:

    def someFunction(someinput)
    #create lots of variables
    #do stuff with those variables
    return output

    #some code
    output = someFunction(input)
    #more code

    Regards,
    Stephen Thorne.
     
    Stephen Thorne, Jan 21, 2005
    #3
  4. Johnny Lin

    John Machin Guest

    Johnny Lin wrote:
    > Hi!
    >
    > Is there a way to automate the unbinding of multiple variables? Say

    I
    > have a list of the names of all variables in the current scope via
    > dir(). Is there a command using del or something like that that will
    > iterate the list and unbind each of the variables?

    Yes. It's called "return".
     
    John Machin, Jan 21, 2005
    #4
  5. John Hunter wrote:
    > >>>del locals()['x']

    The locals() dictionary will only modify values in a module's top-level
    code (i.e. when the expression "locals() is globals()" is true).
     
    Leif K-Brooks, Jan 21, 2005
    #5
  6. Johnny Lin

    Johnny Lin Guest

    thanks everyone for the replies!

    John Hunter, yep, this is Johnny Lin in geosci :).

    re using return: the problem i have is somewhere in my code there's a
    memory leak. i realize return is supposed to unbind all the local
    variables, but since the memory leak is happening despite return, i
    thought it might help me track down the leak if i unbound everything
    explicitly that i had defined in local scope before i returned. or if
    anyone has recomm. on plugging leaks, would be thankful for any
    pointers there too.

    my understanding about locals() from the nutshell book was that i
    should treat that dictionary as read-only. is it safe to use it to
    delete entries?

    thanks again!
     
    Johnny Lin, Jan 21, 2005
    #6
  7. Johnny Lin wrote:
    > my understanding about locals() from the nutshell book was that i
    > should treat that dictionary as read-only. is it safe to use it to
    > delete entries?


    No it's not:

    py> def f():
    .... x = 1
    .... del locals()['x']
    .... print x
    ....
    py> f()
    1
    py> def f():
    .... x = 1
    .... del x
    .... print x
    ....
    py> f()
    Traceback (most recent call last):
    File "<interactive input>", line 1, in ?
    File "<interactive input>", line 4, in f
    UnboundLocalError: local variable 'x' referenced before assignment

    Steve
     
    Steven Bethard, Jan 21, 2005
    #7
  8. Johnny Lin <> wrote:
    ...
    > my understanding about locals() from the nutshell book was that i
    > should treat that dictionary as read-only. is it safe to use it to
    > delete entries?


    Speaking as the Nutshell author: it's "safe", it just doesn't DO
    anything. I _hoped_ locals() would become a dictionary-proxy giving at
    least some *warning* about futile attempts to modify things through it,
    on the basis of "errors shouldn't pass silently", but it just didn't
    happen (yet). Nevertheless, any modifications to locals() are utterly
    futile (within a function).

    Unfortunately, I believe the only way to "delete locals" automatically
    as you desire is through exec statements (which will inevitably turn off
    the normal optimizations and make the whole function unbearably slow).
    I also suspect this won't help you one bit in tracking down your leaks.
    I would rather suggest you look into module gc...


    Alex
     
    Alex Martelli, Jan 21, 2005
    #8
  9. Alex Martelli wrote:
    > Nevertheless, any modifications to locals() are utterly
    > futile (within a function).


    Evil hack that makes modifications to locals() not quite as futile:

    py> import sys
    py> import ctypes
    py> def f():
    .... x = 1
    .... locals()['x'] = 2
    .... ctypes.pythonapi.PyFrame_LocalsToFast(
    .... ctypes.py_object(sys._getframe()), 0)
    .... return x
    ....
    py> f()
    2

    Warning! NEVER do this! ;)

    (Also note that you can't del or add variables in this manner -- only
    modify them.)

    Steve
     
    Steven Bethard, Jan 22, 2005
    #9
  10. On 21 Jan 2005 11:13:20 -0800, "Johnny Lin" <> wrote:

    >thanks everyone for the replies!
    >
    >John Hunter, yep, this is Johnny Lin in geosci :).
    >
    >re using return: the problem i have is somewhere in my code there's a
    >memory leak. i realize return is supposed to unbind all the local
    >variables, but since the memory leak is happening despite return, i
    >thought it might help me track down the leak if i unbound everything
    >explicitly that i had defined in local scope before i returned. or if
    >anyone has recomm. on plugging leaks, would be thankful for any
    >pointers there too.


    It helps to clue people into what your real goal is ;-) (Your initial post
    said nothing about memory leaks).

    Step 1: How do you know you have a memory leak? Python retains some memory
    in internal free pools rather than returning it to the OS, so you might not
    have a memory leak at all, in the true sense.

    If you are having a real memory leak, look first at any C extensions you've
    written yourself, then at other's alpha/beta stuff you may be using. Core CPython
    is probably the last place to look ;-)

    If you are creating reference loops, I think some may be uncollectable.

    I'm not sure how you are detecting "memory leaks," but whatever the method,
    if you can write a test harness that will create a zillion of each suspect
    thing and delete them in turn, and print out your detection data -- even if
    you have to run separate processes to do it, that might narrow down your search.
    E.g., if you write a little test.py that takes a command line argument to choose
    which object to create zillions of, and print out leak evidence, then you could
    run that systematically via popen etc. Or just run test.py by hand if you don't
    have that many suspects (hopefully the case ;-)

    >
    >my understanding about locals() from the nutshell book was that i
    >should treat that dictionary as read-only. is it safe to use it to
    >delete entries?

    Well, it's not read-only, but it doesn't write through to the actual locals.
    Think of it as a temp dict object with copies of the local name:value bindings,
    but changing anything in it only changes the temp dict object in the usual way. UIAM ;-)

    (OTOH, deletions of actual local bindings do seem to propagate back into a previously
    bound value of locals on exit, and a new call to locals() seems to return the same identical
    object as before, so I'm not sure I believe the <type 'dict'>, unless it has a special slot
    and it is automatically updated at exit. But a local bare name assignment or deletion doesn't
    immediately propagate. But it does on exit. So the <type 'dict'> returned by locals() has
    a special relationship to the function it reflects, if it is otherwise a normal dict:

    >>> def foo(x):

    ... d = locals()
    ... print '1:',id(d), type(d), d
    ... del x
    ... print '2:',id(d), type(d), d
    ... del d['x']
    ... print '3:',id(d), type(d), d
    ... y = 123
    ... print '4:',id(d), type(d), d
    ... d['z'] = 'zee'
    ... print '5:',id(d), type(d), d
    ... return d, locals()
    ...
    >>> dret, endinglocals = foo('arg passed to foo')

    1: 49234780 <type 'dict'> {'x': 'arg passed to foo'}
    2: 49234780 <type 'dict'> {'x': 'arg passed to foo'}
    3: 49234780 <type 'dict'> {}
    4: 49234780 <type 'dict'> {}
    5: 49234780 <type 'dict'> {'z': 'zee'}
    >>> dret

    {'y': 123, 'z': 'zee', 'd': {...}}
    >>> endinglocals

    {'y': 123, 'z': 'zee', 'd': {...}}
    >>> dret is endinglocals

    True
    >>> dret['d'] is dret

    True
    (the {...} is an indication of the recursive reference)

    Note that at 2: the del x was not reflected, nor did the y = 123 show at 4:
    But the d['z'] showed up immediately, as you might expect ... but d['z'] also
    in that last returned locals(), which you might not expect, since there was
    no assignment to bare z. But they are apparently the same dict object, so you
    would expect it. So maybe there is some kind of finalization at exit like closure
    building. Anyway, d = dict(locals()) would probably behave differently, but I'm
    going to leave to someone else ;-)

    Regards,
    Bengt Richter
     
    Bengt Richter, Jan 22, 2005
    #10
  11. Johnny Lin

    Nick Coghlan Guest

    Bengt Richter wrote:
    > (OTOH, deletions of actual local bindings do seem to propagate back into a previously
    > bound value of locals on exit, and a new call to locals() seems to return the same identical
    > object as before, so I'm not sure I believe the <type 'dict'>, unless it has a special slot
    > and it is automatically updated at exit. But a local bare name assignment or deletion doesn't
    > immediately propagate. But it does on exit. So the <type 'dict'> returned by locals() has
    > a special relationship to the function it reflects, if it is otherwise a normal dict:


    CPython frames keep two copies of their locals around - the "fast" locals, which
    are actually used by the code (and stored in an array for fast access, hence the
    name), and a Python-readable copy in a dictionary (this is the dictionary
    returned by locals()).

    Various things trigger updates from the fast locals to the locals dictionary.
    Updates in the other direction are far less common (exec without an 'in' clause,
    star imports, and monkeying with the frame via the C API are the only cases I am
    aware of).

    Cheers,
    Nick.



    --
    Nick Coghlan | | Brisbane, Australia
    ---------------------------------------------------------------
    http://boredomandlaziness.skystorm.net
     
    Nick Coghlan, Jan 23, 2005
    #11
  12. Johnny Lin

    Johnny Lin Guest

    thanks again for all the help! especially the advice on ideas of
    tracking down the memory leak :). (sorry for not mentioning it
    earlier...i had thought deleting everything might be a quick and dirty
    way short-term fix. :p)

    best,
    -Johnny
     
    Johnny Lin, Jan 24, 2005
    #12
    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. Sin

    Re: UNbinding a socket

    Sin, Jun 23, 2003, in forum: C++
    Replies:
    2
    Views:
    13,908
  2. Michael Furman

    Re: (OT) UNbinding a socket

    Michael Furman, Jun 23, 2003, in forum: C++
    Replies:
    0
    Views:
    1,431
    Michael Furman
    Jun 23, 2003
  3. Richard Spooner

    Unbinding sockets in threads..

    Richard Spooner, Aug 3, 2004, in forum: Python
    Replies:
    0
    Views:
    353
    Richard Spooner
    Aug 3, 2004
  4. Roger

    Tkinter unbinding

    Roger, Dec 18, 2008, in forum: Python
    Replies:
    17
    Views:
    3,007
    fabien
    Dec 4, 2011
  5. Roger
    Replies:
    7
    Views:
    729
    Roger
    Jan 13, 2009
Loading...

Share This Page