简体   繁体   中英

Semantic error with scope/namespace with return function in python

While trying to understand return and scope I tried writing the function below but found that it only returns the value of x evaluated as x += 20

 def this_is_return(x):
    """
    takes as input x and passes it to a second function which operates 
    on it returns to first function which operates on it more before 
    returning value to console
    """
     def second_function(x):
         x *= 2
         print(x)
         return x
     second_function(x)
     x += 20
     return x

When written as below the function works as expected. But I am really interested in what I am not understanding about the limits of return with respect to the initial value x. My block diagramming skills are nebulous.

 def this_is_return(x):
    """
    takes as input x and passes it to a second function, which 
    operates on it and assigns it to c, returns c to
    function assigned to d; first function then operates on it more 
    before returning value to console
    """
    def second_function(x):
        c = x * 2
        print(c)
        return c
    d = second_function(x)
    x = d + 20
    return x

If I understand your question correctly, the heart of the problem is that a reasonable person might expert that x *= 2 doubles the value of x . It does, but the doubling doesn't persist:

>>> def second_function(x):
...          x *= 2
...          print(x)
...          return x
... 
>>> x = 10 ; second_function(x)
20
20
>>> x
10

Let's take this step by step:

  1. def second_function(x):

    x points to the data that was passed in.

  2. x *= 2

    The data that was passed in was multiplied by two and, locally, x points to a new number that is double the old number. The memory location that contains the old number is unaffected.

    Integers are immutable. They cannot be changed "in-place."

  3. print(x); return x

    The local x is printed and returned.

In the first_function, though, x is still pointing to the original data. The original data was never changed.

In sum, x *= 2 does not change the data in-place. It causes x to point to new number. Other variables which point to the old data are unaffected.

Alternate version using mutable variables

Instead of passing an integer, let's pass in a list:

>>> def third_function(x):
...     x[0] *= 2
...     print(x)
... 
>>> x = [10]; third_function(x)
[20]
>>> x
[20]

As you can see, the change to the list x persists. Lists are mutable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM