yurib
yurib

Reputation: 8147

about python scopes

I've read about python scopes and browsed questions here on stackoverflow but theres something i'd like to clarify.

I'm extracting a piece of code to a function, from what i used to it should take all the variables it's using as parameters. But, in python the variable address is determined at runtime so theres actually no need for the parameters. Since i'm new to python i wanted to know if there are other implications or conventions i should know about.

x = 5
x += 1
print x

is there any difference between the following refactoring of the above code :

def f(x):
  x += 1
  return x

x = 5
x = f(x)
print x

and:

def f():
  x++

x = 5
f()
print x

If not then, is one of the ways more commonly used or preferred in python ?

Upvotes: 0

Views: 274

Answers (2)

eyquem
eyquem

Reputation: 27585

I upvote the question for two reasons:

1)

  • importing the notation x++ from other languages (C++ and Java) is a venial sin; who has never been absent-minded ?
  • not testing codes deserves a downvote, that's right, because it denotes that no tests have been performed to try to obtain oneself a certain number of observations and that's baaad
  • however I find the desire to understand notions concerning scopes, namespaces, global/local more commendable than the faults to be reproached

2)

It is certainly an unsatisfactory situation to be downvoted because of an approximate question while receiving an upvoted answer that contains itself some inadequate terms according to me. Terminology is particularly important in subjects in which controversial debates and confusionning descriptions may happen.

For exemple, for

def f(x): 
    x++ 
    return x
  • I wouldn't say that f receives an argument x, but that f receives x as an argument.
  • x is not incremented; rather: another object is created with a value resulting of the incrementation of the value of initial x

  • f doesn't returns x+1 , it returns the new object with the incremented value

EDIT 1

# f takes an argument x

In the call f(x) , I wouldn't say that f receives an argument x, because x isn't an argument in the absolute. x "becomes" an argument only relatively to a function, at the moment when it is passed to the function. So I rather say that in the call f(x) , the function f receives x AS an argument.

It may happen that one says "the argument Y" one time, as an understatement to express "Y , considered at a moment when it is passed as an argument to a function". This understatement is shorter; but what I think is that in a precise explanation such an easy way to express must be banned.

#Increments x

Refering to the code written in the question (case 1), this sentence is ambiguous because of the function written with a parameter x: does x refer to the x in the function or the x outside ? You'll say I nitpick, but for a newbie that doesn't know the data model and the working of functions well, the question is valid. What does f(x) mean in Python ? , is the x passed by value or passed by reference ? It could be that the operations inside f could change the x outside, why not, that's precisely what is in discussion, no ? That's why it is preferable to name the parameter of f with a different name than any of the names of the outside objects; I think the same as for the previous sentence: in a precise explanation, only cautious sentences and codes should be employed, to avoid confusionning ambiguities:

def f(N):
    N += 1
    return N
x = 5
x = f(x)
print x

And it should be explained that the instruction N += 1 triggers the creation of a new object with value incremented and that the local identifier N is rebound to this new object. And at this point, the global identifier x is still bound to the same object as before the call.

# returns x + 1

f doesn't returns x+1 , it returns the new object newly assigned to N with the incremented value

# the global x is not affected

What does it mean ? Before , global x has a value 5. After, global x has a value 6. During the execution of the operations inside f, the global x isn't affected, that's right: it is only when the new object (in fact its address..) is returned to the outside of f, and that the assignement x = f(x) is executed that global x is affected. But this sentence "the global x is not affected" is placed after "returns x + 1 ". No really, I understand nothing in such explanations.

End of EDIT 1

.

.

Concerning the second case

def f():
    global x 
    x += 1
  • I prefer to say that f has no argument than it has no parameter
  • It doesn't increments the global x, it provokes a new assignement of the global identifier x to a new object with incremented value.

EDIT 2

In this case, it isn't possible to use another name than x inside the function, otherwise the exemple would mean another thing.

def f():
    global x
    x += 1
x = 5
f()
print x

# f has no arguments

Why the hell did I write "I prefer to say that f has no argument than it has no parameter" to comment that ? I still wonder. At first, I had written "I prefer to say that f has no parameter than it has no argument" , thinking to the definition of f . I don't know why, I "corrected" by reversing the sentence and the result expresses nothing of what I think. I am completely puzzled.

Precisely, I think that the correct manners to express are :

  • in the definition of the function, f -> HAS no PARAMETER,

  • in the call f() , f -> RECEIVES no ARGUMENTS.

# Increments the global x

It doesn't increments the global x, it provokes a new assignement of the global identifier x to a new object with incremented value.

End of EDIT 2

.

It may seem minor nuances , and I am sure that it is a way to express things in a condensed manner.

But for me it is very important because, when a newbie, I had a lot of difficulty because of this kind of imprecision to understand all these questions linked to the peculiar data model of Python that are badly explained in the official docs of Python and that are debated in awkard discussions, such as the one concerning "pass by value or pass by reference" for exemple (that has no sense in Python), in which the terms are floating from right to left and left to right like on a sea of vagueness.

Upvotes: 3

Eli Bendersky
Eli Bendersky

Reputation: 273646

It's preferred not to use global variables, if not absolutely necessary. That said, in the second example you'd need global x declared before you refer to x.

So, first way:

  • f takes an argument x
  • Increments x
  • returns x + 1
  • the global x is not affected

The second way:

def f():
  global x
  x += 1

x = 1
f()
  • f has no arguments
  • Increments the global x

P.S. Python has no ++ operator. x += 1 is used instead

Upvotes: 3

Related Questions