2

Let's for example define a class and a function

class class1(object):
    """description of class"""
    pass

def fun2(x,y):
    x.test=1;
    return x.value+y

then define a class instance and run it as a local variable in the function

z=class1()
z.value=1
fun2(z,y=2)

However, if you try to run the code

z.test

a result 1 would be returned.

That was, though the attribute to x was done inside the fun2() locally, it extended to class instance x globally as well. This seemed to violate the first thing one learn about the python function, the argument stays local unless being defined nonlocal or global.

How could this happen? Why the attribute to class inside a function extend outside the function.

6
  • 1
    Your class is mutable much like a list or dict would be changed inside the function as well. Commented Jan 20, 2021 at 12:47
  • 1
    Here is a very good explanation on discuss.python. discuss.python.org/t/… Commented Jan 20, 2021 at 12:54
  • 1
    If you want a more detailed explanation I can write an answer. but basically, calling a function with arguments is assigning those variables to the arguments. In your case it would be like x = z outside the function. The same assignment rules apply regardless of type. The reason a str or int appears to create a copy(it actually doesn't) is because they're immutable. Commented Jan 20, 2021 at 13:12
  • Please clarify your question. Variables are local, objects are not. Did you expect the instance to be copied into the function? Commented Jan 20, 2021 at 13:12
  • Does this answer your question? Are python variables pointers? or else what are they? Commented Jan 20, 2021 at 13:14

1 Answer 1

2

I have even stranger example:

def fun3(a):
    b=a
    b.append(3)
    
mya = [1]
fun3(mya)

print(mya)

[1, 3]
> 

I "copy" the array to a local variable and when I change it, the global one changes as well.

The problem is that the parameters are not passed by a value (basically as a copy of the values). In python they are passed by reference. In C terminology the function gets a pointer to the memory location. It's much faster that way.

Some languages will not let you to play with private attributes of an instance, but in Python it's your responsibility to make sure that does not happen. One other rule of OOP is that you should change the internal state of an instance just by calling its methods. But you change the value directly.

Python is very flexible and allows you to do even the bad things. But it does not push you.

I always argue to have always at least vague understanding of the underlaying structure of any higher level language (memory model, how the variables are passed etc.). There is another argument for having some C/C++ knowledge. Most of the higher level languages are written in them or at least are inspired by them. A C++ programmer would see clearly what is going on.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.