When is a link created, and when is a new block of memory allocated and then copied?

>>> d {1: 1, 2: 2, 3: 3} >>> lst = [d, d] >>> c=lst[0] >>> c[1]=5 >>> lst [{1: 5, 2: 2, 3: 3}, {1: 5, 2: 2, 3: 3}] 

When lst = [d, d] , are lst[0] and lsg[1] both references to memory block d instead of creating two memory blocks and copying their contents d respectively?

When c=lst[0] , is c just a reference to the memory occupied by lst[0] , instead of creating a new memory block and copying the contents from lst[0] ?

In Python, when is a link created that points to an existing block of memory, and when is a new block of memory allocated and then copied?

This Python language function is different from C. What is the name of this language function?

Thanks.

+7
python
source share
3 answers

All variables (and other containers, such as dictionaries, lists, and object attributes) contain references to objects. Memory allocation occurs when an object is created. A simple assignment always creates another reference to an existing object. For example, if you have:

 a = [1, 2, 3] b = a 

Then b and a point to the same object, a list. You can verify this with the is statement:

 print(b is a) # True 

If you change a , then b also changes, because these are two names for the same object.

 a.append(4) print(b[3] == 4) # True print(b[3] is a[3]) # also True 

If you want to create a copy, you must do it explicitly. Here are some ways to do this:

  • For lists, use the slice: b = a[:] .
  • For many types, you can use the type name to copy an existing object of this type: b = list(a) . Creating your own classes is a good approach if you need a copy function.
  • The copy module has methods that you can use to copy objects (either shallow or deep).

For immutable types, such as strings, numbers, and tuples, you never need to make a copy. You can “modify” these values ​​by referring to different ones.

The best way to describe this is probably "all that is an object." In C, "primitive" types, such as integers, are handled differently than arrays. In Python, this is not so: all values ​​are stored as references to objects — even integers.

+7
source share

This paragraph from a Python tutorial should help you figure it out:

Objects have personality, and several names (in several areas) can be associated with the same object. This is called an alias in other languages. Usually this is not evaluated at a glance at Python, and they can be safely ignored when working with immutable basic types (numbers, strings, tuples). However, anti-aliasing may have an amazing effect on the semantics of Python code with mutable objects such as lists, dictionaries, and most other types. This is usually used in the interests of the program, since aliases behave like pointers in some respects. For example, passing an object is cheap because the implementation is performed only by a pointer; and if the function changes the object passed as an argument, the caller will see the change - this eliminates the need for two different arguments as in Pascal.


To answer your individual questions in more detail:

When lst = [d, d], lst [0] and lst [1] are both references to memory block d, instead of creating two memory blocks and copying the contents of d into them respectively?

Not. They do not apply to memory unit d . lst[0] and lst[1] smooth the same object as d at this point in time. Evidence. If you assigned d to a new object after initializing the list, lst[0] and lst[1] will not be changed. If you mutate an object with the alias d , then the mutation is visible lst[0] and lst[1] , because they have the same object.

When c = lst [0] is just a reference to the memory occupied by lst [0], instead of creating a new memory block and copying the contents from lst [0]?

No again. This is not a reference to the memory occupied by lst[0] . Evidence. If you assign lst[0] to a new object, c will not change. If you modify a mutable object (for example, the dictionary pointed to by lst[0] ), you will see a change in c because c refers to the same object as the original dictionary.

In Python, when is a link created that points to an existing block of memory, and when is a new block of memory allocated and then copied?

Python really does not work with "blocks of memory" in the same way as C. This is an abstraction from this. Whenever you create a new object and assign it to a variable, you obviously got allocated memory for that object. But you will never work with this memory directly; you work with references to objects in this memory.

These links are values ​​that are assigned to symbolic names, AKA variables, AKA aliases. "pass-by-reference" is a concept from pointer-based languages ​​such as C and C ++, and does not apply to Python. There is a blog post that I think is best suited for this topic.

It is often claimed that Python is pass-by-value, pass-by-reference or pass-by-object-reference. The truth is that no matter how you think about it, if you understand that the entire language specification is just an abstraction for working with names and objects. Java and Ruby have similar runtime models, but Java documents call this pass-by-value, while Ruby documents call this pass-by-reference. Python docs remain neutral on this, so it's best not to speculate and just see things for them.

This Python language function is different from C. What is the name of this language function?

Associating names with objects is called name binding. Allowing the binding of multiple names (in potentially multiple areas) to the same object is known as anti-aliasing. You can learn more about aliasing in the Python tutorial and on Wikipedia .

You might find it helpful to read the modeling documentation , which talks more about name binding and scope.

+4
source share

In short; Python is pass by reference. Objects are created, and memory is allocated when they are built. Referencing objects do not allocate more memory unless you create new objects or expand existing objects ( list.append() )

This post Whether Python is by reference or pass by value , this is very well covered.

As a side note; if you are worried about how memory is allocated in a managed programming language such as Python, then you are probably using the wrong language and / or optimizing prematurely. Just like memory management in Python is an implementation, since there are many Python implementations; CPython (which you are probably using); Jython, IronPython, PyPy, MicroPython, etc.

+1
source share

All Articles