To clarify how Python handles two equal objects
Jen Kris
jenkris at tutanota.com
Sat Jan 14 18:30:48 EST 2023
Avi,
Your comments go farther afield than my original question, but you made some interesting additional points. For example, I sometimes work with the C API and sys.getrefcount may be helpful in deciding when to INCREF and DECREF. But that’s another issue.
The situation I described in my original post is limited to a case such as x = y where both "x" and "y" are arrays – whether they are lists in Python, or from the array module – and the question in a compiled C extension is whether the assignment can be done simply by "x" taking the pointer to "y" rather than moving all the data from "y" into the memory buffer for "x" which, for a wide array, would be much more time consuming than just moving a pointer. The other advantage to doing it that way is if, as in my case, we perform a math operation on any element in "x" then Python expects that the same change to be reflected in "y." If I don’t use the same pointers then I would have to perform that operation twice – once for "x" and once for "y" – in addition to the expense of moving all the data.
The answers I got from this post confirmed that it I can use the pointer if "y" is not re-defined to something else during the lifespan of "x." If it is then "x" has to be restored to its original pointer. I did it that way, and helpfully the compiler did not overrule me.
Jan 13, 2023, 18:41 by avi.e.gross at gmail.com:
> Jen,
>
> This may not be on target but I was wondering about your needs in this category. Are all your data in a form where all in a cluster are the same object type, such as floating point?
>
> Python has features designed to allow you to get multiple views on such objects such as memoryview that can be used to say see an array as a matrix of n rows by m columns, or m x n, or any other combo. And of course the fuller numpy package has quite a few features.
>
> However, as you note, there is no guarantee that any reference to the data may not shift away from it unless you build fairly convoluted logic or data structures such as having an object that arranges to do something when you try to remove it, such as tinkering with the __del__ method as well as whatever method is used to try to set it to a new value. I guess that might make sense for something like asynchronous programming including when setting locks so multiple things cannot overlap when being done.
>
> Anyway, some of the packages like numpy are optimized in many ways but if you want to pass a subset of sorts to make processing faster, I suspect you could do things like pass a memoryview but it might not be faster than what you build albeit probably more reliable and portable.
>
> I note another odd idea that others may have mentioned, with caution.
>
> If you load the sys module, you can CAREFULLY use code like this.
>
> a="Something Unique"
> sys.getrefcount(a)
> 2
>
> Note if a==1 you will get some huge number of references and this is meaningless. The 2 above is because asking about how many references also references it.
>
> So save what ever number you have and see what happens when you make a second reference or a third, and what happens if you delete or alter a reference:
>
> a="Something Unique"
> sys.getrefcount(a)
> 2
> b = a
> sys.getrefcount(a)
> 3
> sys.getrefcount(b)
> 3
> c = b
> d = a
> sys.getrefcount(a)
> 5
> sys.getrefcount(d)
> 5
> del(a)
> sys.getrefcount(d)
> 4
> b = "something else"
> sys.getrefcount(d)
> 3
>
> So, in theory, you could carefully write your code to CHECK the reference count had not changed but there remain edge cases where a removed reference is replaced by yet another new reference and you would have no idea.
>
> Avi
>
>
> -----Original Message-----
> From: Python-list <python-list-bounces+avi.e.gross=gmail.com at python.org> On Behalf Of Jen Kris via Python-list
> Sent: Wednesday, January 11, 2023 1:29 PM
> To: Roel Schroeven <roel at roelschroeven.net>
> Cc: python-list at python.org
> Subject: Re: To clarify how Python handles two equal objects
>
> Thanks for your comments. After all, I asked for clarity so it’s not pedantic to be precise, and you’re helping to clarify.
>
> Going back to my original post,
>
> mx1 = [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]
> arr1 = mx1[2]
>
> Now if I write "arr1[1] += 5" then both arr1 and mx1[2][1] will be changed because while they are different names, they are the assigned same memory location (pointer). Similarly, if I write "mx1[2][1] += 5" then again both names will be updated.
>
> That’s what I meant by "an operation on one is an operation on the other." To be more precise, an operation on one name will be reflected in the other name. The difference is in the names, not the pointers. Each name has the same pointer in my example, but operations can be done in Python using either name.
>
>
>
>
> Jan 11, 2023, 09:13 by roel at roelschroeven.net:
>
>> Op 11/01/2023 om 16:33 schreef Jen Kris via Python-list:
>>
>>> Yes, I did understand that. In your example, "a" and "b" are the same pointer, so an operation on one is an operation on the other (because they’re the same memory block).
>>>
>>
>> Sorry if you feel I'm being overly pedantic, but your explanation "an operation on one is an operation on the other (because they’re the same memory block)" still feels a bit misguided. "One" and "other" still make it sound like there are two objects, and "an operation on one" and "an operation on the other" make it sound like there are two operations.
>> Sometimes it doesn't matter if we're a bit sloppy for sake of simplicity or convenience, sometimes we really need to be precise. I think this is a case where we need to be precise.
>>
>> So, to be precise: there is only one object, with possible multiple names to it. We can change the object, using one of the names. That is one and only one operation on one and only one object. Since the different names refer to the same object, that change will of course be visible through all of them.
>> Note that 'name' in that sentence doesn't just refer to variables (mx1, arr1, ...) but also things like indexed lists (mx1[0], mx1[[0][0], ...), loop variables, function arguments.
>>
>> The correct mental model is important here, and I do think you're on track or very close to it, but the way you phrase things does give me that nagging feeling that you still might be just a bit off.
>>
>> --
>> "Peace cannot be kept by force. It can only be achieved through understanding."
>> -- Albert Einstein
>>
>> --
>> https://mail.python.org/mailman/listinfo/python-list
>>
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>
More information about the Python-list
mailing list