0

If the title is a bit cryptic (I have no idea how to put my issue in one title) here the explanation.

I have a global variable

ex = False
orig = id(ex)

Then, I have two functions:

def start(test):
   print("Start")
   global ex
   while True:
       if id(ex) == orig:
       print("same")
   else:
       print(orig)
       print(id(ex))

def end(test):
   print("End")
   global ex
   ex = True
   while True:
       if id(ex) == orig:
       print("same")
   else:
       print(orig)
       print(id(ex))

When I enter the "end-function" the id of "ex" in the function is not the same as the original id. So, they are basically two different variables.

I do not understand why this happens. I mean, I know that it happens because I do set "ex = True" (because if I skip this line, the id is the same). But I do not understand why. I thought the idea of global keyword is exactly to make it possible to set global variables inside a function. Using global variables in a function

Skobo Do
  • 49
  • 6
  • 3
    Variables don't have IDs. Objects have IDs. Seeing a different ID for a different object is perfectly normal. – user2357112 Jan 05 '23 at 14:39
  • 1
    looks like what you are trying to do should rather be done inside a class. So you can have different instances of the class that have a method start and end. Could you explain a bit what you are trying to achieve? – Sembei Norimaki Jan 05 '23 at 14:39
  • @user2357112 everything is an object in python.... – Skobo Do Jan 05 '23 at 14:42
  • 2
    @SkoboDo: "Everything" is a misleadingly broad term. What people mean when they say "everything is an object" is that Python has no non-object "primitive" types. It doesn't mean that variables are objects. – user2357112 Jan 05 '23 at 14:44
  • @user2357112 what are actually talking about? If I define x = 1 and then id(x) I get an id. By your own defintion "only objects have id" the x is an object? So what your point then? – Skobo Do Jan 05 '23 at 14:46
  • 2
    You get the ID *of the `1` object*, not the ID of the `x` variable. – user2357112 Jan 05 '23 at 14:48
  • 1
    `x` is not an object. It's a *name* in the Python source code that *refers* to an object. See https://nedbatchelder.com/text/names.html – chepner Jan 05 '23 at 14:53

1 Answers1

1

The problem is that bools are immutual. So when you change the global variable ex, you change to where it points to (i.e., a different object). You can easily simulate that:

>>> b=True
>>> id(b)
140715296352080
>>> b=False
>>> id(b)
140715296352112
>>> id(True)
140715296352080
>>> id(False)
140715296352112

If your variable would be of a mutual type and you change a value in it, it would not change the id. In the following example I place a wrapper around the bool

>>> class MyBool():
...   val = False
...
>>> mb = MyBool()
>>> def foo():
...   global mb
...   print(id(mb))
...   mb.val = True
...   print(id(mb))
...
>>> foo()
2359703595472
2359703595472

And the id of the variable stays uncahnged.

In general, in python variables point to object in the global or local storage. When you change the "value" of a variable you need to distinguish between mutable and immutable types.

  1. When the type is mutable: the value in the memory, which is pointed by the variable is changed.
  2. When the immutable: The pointer itself is changed to a memory location that contains the new value, while keeping the old one unchanged.
sim
  • 1,148
  • 2
  • 9
  • 18
  • This doesn't really have anything to do with mutability; assignments to a name *never* change a value, only what value the name refers to. – chepner Jan 05 '23 at 14:47