python atomic data types

Question:

It was written here that Python has both atomic and reference object types. Atomic objects are: int, long, complex.
When assigning atomic object, it’s value is copied, when assigning reference object it’s reference is copied.

My question is:
why then, when i do the code bellow i get ‘True’?

a = 1234
b = a
print id(a) == id(b)

It seems to me that i don’t copy value, i just copy reference, no matter what type it is.

Asked By: Artem Sliusar

||

Answers:

int types are immutable.
what you see is the reference for the number 1234 and that will never change.

for mutable object like list, dictionary you can use

import copy
a = copy.deepcopy(b)
Answered By: nivhanin

Actually like @spectras said there are only references but there are immutable objects like floats, ints, tuples. For immutable objects (apart from memory consumption) it just does not matter if you pass around references or create copies.

The interpreter even does some optimizations making use of numbers with the same value being interchangeable making checking numbers for identity interesting because eg for

a=1
b=1
c=2/2
d=12345 
e=12345*1

a is b is true and a is c is also true but d is e is false (== works normally as expected)

Immutable objects are atomic the way that changing them is threadsafe because you do not actually change the object itself but just put a new reference in a variable (which is threadsafe).

Answered By: janbrohl

Assignment (binding) in Python NEVER copies data. It ALWAYS copies a reference to the value being bound.

The interpreter computes the value on the right-hand side, and the left-hand side is bound to the new value by referencing it. If expression on the right-hand side is an existing value (in other words, if no operators are required to compute its value) then the left-hand side will be a reference to the same object.

After

a = b

is executed,

a is b

will ALWAYS be true – that’s how assignment works in Python. It’s also true for containers, so x[i].some_attribute = y will make x[i].some_attribute is y true.

The assertion that Python has atomic types and reference types seems unhelpful to me, if not just plain untrue. I’d say it has atomic types and container types. Containers are things like lists, tuples, dicts, and instances with private attributes (to a first approximation).

As @BallPointPen helpfully pointed out in their comment, mutable values can be altered without needing to re-bind the reference. Since immutable values cannot be altered, references must be re-bound in order to refer to a different value.

Edit: Recently reading the English version of the quoted page (I’m afraid I don’t understand Russian) I see “Python uses dynamic typing, and a combination of reference counting and a cycle-detecting garbage collector for memory management.” It’s possible the Russian page has mistranslated this to give a false impression of the language, or that it was misunderstood by the OP. But Python doesn’t have “reference types” except in the most particular sense for weakrefs and similar constructs.

Answered By: holdenweb

Python atomic for shared data types.

https://sharedatomic.top

The module can be used for atomic operations under multiple processs and multiple threads conditions. High performance python! High concurrency, High performance!

atomic api Example with multiprocessing and multiple threads:

You need the following steps to utilize the module:

  1. create function used by child processes, refer to UIntAPIs, IntAPIs, BytearrayAPIs, StringAPIs, SetAPIs, ListAPIs, in each process, you can create multiple threads.

     def process_run(a):
       def subthread_run(a):
         a.array_sub_and_fetch(b'x0F')
    
       threadlist = []
       for t in range(5000):
           threadlist.append(Thread(target=subthread_run, args=(a,)))
    
       for t in range(5000):
           threadlist[t].start()
    
       for t in range(5000):
           threadlist[t].join()
    
  2. create the shared bytearray

    a = atomic_bytearray(b'ab', length=7, paddingdirection='r', paddingbytes=b'012', mode='m')
    
  3. start processes / threads to utilize the shared bytearray

     processlist = []
    
     for p in range(2):
    
       processlist.append(Process(target=process_run, args=(a,)))
    
     for p in range(2):
    
       processlist[p].start()
    
     for p in range(2):
    
       processlist[p].join()
    
     assert a.value == int.to_bytes(27411031864108609, length=8, byteorder='big')
    
Answered By: Xiquan Ren