#๐Ÿ”’ Can a function modify variables declared outside their scope?

43 messages ยท Page 1 of 1 (latest)

wispy tundra
#

Hello, consider this code:

def greet(message):
  print(message)
  message = "New message"
  anotherMessage = "def"


message = "Hello World"
anotherMessage = "abcd"
greet(message)
print(message)
print(anotherMessage)

I was testing if it was possible to produce side effects by modifying other global variables but it seem we can't? Can someone explain why please.

Do we have parameters pass by ref and pass by value in python?

waxen fernBOT
#

@wispy tundra

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

plain crypt
#

you can do it by using the global and nonlocal keywords
without them, any assignment to a variable inside a function makes it create a local variable
"pass by ref and pass by value" does not make sense, a language only uses 1 calling convention, and for python neither of those accurately describe the behavior
its more like "pass by value, where the value is a reference", and whats important is that name = expression is reassignment of the reference, not rewriting the object at that reference if there already is a name variable

signal ice
#

you can always freely mutate globals without a special declaration, but you cannot reassign

modest dune
empty onyx
wispy tundra
#

ah ok, sorry I didn't see the post

#

really sorry, I thought it wasn't posted

wispy tundra
signal ice
#

that's a mutation

empty onyx
#

You can, that was just an example of how, in your original message, you were passing message in to be mutated

signal ice
#

it's modifying an attribute of an object

tawny valve
#

@wispy tundra note that many of pythons data types such as bool, int, float, string, tuple and frozenset (to name some of those i can name on top of my head) are not internally mutable, so all you can do to "change" such a variable is to reassign it to a new object (because all data types in python are objects)

wispy tundra
#

yep I see, so in python , we don't really have the concept of pass by ref or pass by value? Even though we say everything are objects, we don't use references of the objects? Like for e.g when I try to mutate message for e.g

signal ice
#

it's the data that gets mutated

#

message is a string and strings are immutable

tawny valve
modest dune
tawny valve
#

if you instead pass in an object that is internally mutable such as a list, set or a dict for example you can mutate its content as normal within other scopes, or even access such a global variable without declaring it as global and still mutate it internally as normal as long as you don't try to assign directly to the variable

wispy tundra
#

yepp, I see, will read a bit and came back, but I have an overview now, ty !

#

For the Container, the idea is instead of using an immutable object, like a number, create a class and from that class, the objects will be mutable objects, like container.x is a mutable obj compared with just something like x = 10?

tawny valve
#

the variable is just pointing to the address of the class instance (object), as long as you don't assing to the variable holing it you'll be fine

wispy tundra
#

yupp I see, thanks !

#

sorry once more for the post earlier, didn't saw it was close ๐Ÿ˜ญ , I understand things a bit more now, thanks !

modest dune
wispy tundra
#

By the way quick question, we did say something is immutable, but when we use global, we are just creating another label/reference to that variable?

#

Under the hood it's behaving like the container?

tawny valve
#

remember that there aren't any primitive data types in python, every variable is a reference to an object (and as Carcigenicate so well described it above, you can view it as if they are always automatically self-dereferencing)

wispy tundra
#

yupp I see

modest dune
# wispy tundra By the way quick question, we did say something is immutable, but when we use `g...

global affects how the function is compiled. Without a global statement, if there's an assignment in the function to a variable, all reads and assignments to the variable are compiled as local variable operations. If you include a global statement to the name, reads/assignments are compiled as instructions that also look the name up in the global scope. So, it doesn't create a new name, but changes how names are looked up.

#

On second read, I'm not sure if I interpreted your question correctly.

wispy tundra
#

nope, it was the answer I was looking, how global works, I understand now, with global keyword, we just change the rules of how the interpreter sees things ?

modest dune
#

!e

from dis import dis

a_name = 1

def no_global():
    a_name = 2
    print(a_name)

def with_global():
    global a_name
    a_name = 2
    print(a_name)

dis(no_global)

dis(with_global)
#

You can actually see this if you want to investigate

waxen fernBOT
tawny valve
#

oh, and if you have a global statement in the function for a variable it affects variable assignments even before that line inside that scope

modest dune
#

dis compiles and then disassembles the Python to human-readable bytecode. LOAD_FAST is a lookup of local variables, while LOAD_GLOBAL is, as the name implies, a global lookup.

wispy tundra
#

yep I see

#

Thanks !

waxen fernBOT
#
Python help channel closed for inactivity

This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.