X ([info]fixious) wrote in [info]python_dev,

memory deallocation/clearing

I'm kind of new to Python, so here's what must be a silly question:

What's the best way to get around Python's habit of storing old values in memory addresses? It seems to overwrite or refuse to overwrite rather arbitrarily...

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    Your IP address will be recorded 

  • 10 comments

[info]sciucaro

October 24 2005, 05:11:10 UTC 6 years ago

variables alone can be altered. The only static immutable type of memory would be to store it in a Tuple.

Use (a, b, n...) to make a tuple. It's static memory that's easily indexed.

[info]bloc07

October 24 2005, 05:36:24 UTC 6 years ago

can you explain a little more. I'm not exactly sure what your asking.

[info]omnifarious

October 24 2005, 07:14:55 UTC 6 years ago

Yes, your question is very confusing. Can you give an example of what you mean with code in it so there is no ambiguity?

[info]hythloday

October 24 2005, 08:28:42 UTC 6 years ago

I think you're talking about Python's variable/value metaphor being "binding names", rather than "allocating variables".
>>> # create a list of three variables, and bind it to the name 'a'
>>> a = [1,2,3]
>>> # bind the variable b to the value of a
>>> b = a
>>> # add the value 4 to b
>>> b.append(4)
>>> # print a
>>> a
[1, 2, 3, 4]
>>> # create a list of three variables and bind it to b
>>> b = ['a', 'b', 'c']
>>> # print b
>>> b
['a', 'b', 'c']
>>> # a is unchanged
>>> a
[1, 2, 3, 4]

[info]hythloday

October 24 2005, 08:44:58 UTC 6 years ago

Contrast this with C++:
int main() {
    std::vector< int > a = std::vector< int >();
    a.push_back( 1 );
    a.push_back( 2 );
    a.push_back( 3 );

    std::vector< int >& b = a;
    b.push_back( 4 );
    
    // This doesn't work, but if it did, it would print something like:
    // [ 1, 2, 3, 4 ]
    // std::cout << a << std::endl;
    
    b = std::vector< int >();
    b.push_back( -1 );
    b.push_back( -2 );
    b.push_back( -3 );
    
    // Would print something like:
    // [ -1, -2, -3 ]
    // std::cout << b << std::endl;

    // Would print something like:
    // [ -1, -2, -3 ]
    // std::cout << a << std::endl;
}

[info]babalon_it

October 24 2005, 15:49:18 UTC 6 years ago

in this case, the important change happens when you rebind b (use it on the left side of an equal sign). you're changing it from both b and a referring to the same object (a list) to b referring to an entirely different list.



[info]thedarkproject

October 24 2005, 10:52:29 UTC 6 years ago

In addition to what [info]hythloday said, it's important to bear in mind that function arguments are passed as a copy of the value of the reference. This means that when you pass in a class instance or other mutable object (eg. list, dictionary), it's effectively by reference, but if you pass in an immutable object (eg. integer, string), you're just rebinding the local copy to a new value, which is effectively equivalent to having passed by value.

Without knowing this, it's easy to think that some things are getting arbitrarily altered and other things are not. Once you get into the habit of noting this and that assignment is, as the name implies, assigning a value to a name, and not copying (as it is in C++, for example), things begin to fall into place.

[info]babalon_it

October 24 2005, 15:46:40 UTC 6 years ago

ignore memory addresses entirely.

python variable names are like those yellow post-it notes. you can pick it up and stick it to your chair or to your forehead. you can do certain operations with your chair that you can't do with your head.

if you rebind a variable(put the sticky note on another object), then the old object gets garbage collected eventually and automatically (if it doesn't have any other sticky notes on it).

if you've got something like:

myvariable = 23

you can re-bind myvariable to any other object, for example:
myvariable = (1, 2, 3)
myvariable = 'cat'

you're not creating a copy of myvariable in these cases, nor are you doing anything to the memory addresses, as such, you're re-binding the variable name to an entirely new object.

Does this help at all?

[info]ravendisplayed

October 24 2005, 16:30:53 UTC 6 years ago

To add one thing to what has already been said, when you are looking to make a copy of a simple object, such as non-nested lists and dictionaries you can use the copy.copy() method. If your object is deeply nested, such as a dictionary of lists, you need to use the copy.deepcopy() method.

[info]siege

October 24 2005, 17:52:35 UTC 6 years ago

And if all else fails, you can adjust the garbage collector's behavior using the gc module.
Create an Account
Forgot your login or password?
Facebook Twitter More login options
English • Español • Deutsch • Русский…