Can you allow the variable inside a (local) function to be global? If not, what form can we declare a global variable?
Can you allow the variable inside a (local) function to be global? If not, what form can we declare a global variable?
It has, returning it.
There are definite and "rigid" scopes because it is the best environment - or at least makes the developer's life much easier, because the smaller the scope, the easier it is to manage your variables. Having functions that change the global scope is bad for maintenance, greatly undermines the readability of the code, and has generated many WTF in your project (of course there are many other implications).
But it's not a lost case. Like you, many others before have already felt the need to return some externally-defined variables to the external scope. That's what return
came up with - maybe not exactly like that, but for now it's a cute little story.
That is, if you set foo
within the function and want to export it to the outer scope, just return foo
:
def minhaFuncaoQueNaoFazMagica():
foo = 'qualquer coisa'
...
return foo
In this way, in the outer scope, it would be enough to do:
foo = minhaFuncaoQueNaoFazMagica()
Being explicit as foo
has emerged in this scope, without gambiatic magic .
But then you ask me: Anderson, but does your need to return several function variables? The answer is simple: refatore. Having this need is a clear clue that the way you are doing is not the simplest and you need to redo it. If you need to return several variables, they will be somehow related to each other and probably would be better organized within a class / object. But what if they had nothing to do with each other, would not the class become weird? Yes, but if there is no relationship between the variables, they should not be in the same function.
Just like everything else in nature, you should look for the lowest energy state in your code. It is not enough just to work, it has to work and it does not generate problems in the future. The less you have to go back to maintain that code snippet, the better, then do something consistent.
Yes - Just declare the variable as global at the beginning of the function:
def a():
global b
b = "teste"
a()
print(b)
(print "test")
The keyword nonlocal
can be used in functions declared inside other (nested) functions, and, similarly, allows access and change of variables in "outer" functions - but can not be used in the same so that global
to declare a variable that does not exist in the scope of the outer function, since there may be more than one outer function, and "where" to create the variable would be ambiguous:
In [40]: def a():
...: def b():
...: nonlocal c
File "<ipython-input-40-dbf568c371f7>", line 3
nonlocal c
^
SyntaxError: no binding for nonlocal 'c' found
It's also interesting to note that there is a very big culture that "global variables are bad" and "are gambiarra" - but that's not the case in Python - and I've made that clear.
Before, however, it is worth mentioning that if you are going to use a global variable, it is practical to declare it out of the functions at the beginning of the file so that it is visible. The use of the global
keyword in the functions allows it to be changed in the same way as if it is first declared in a function - but this avoids surprises of the variable appearing "out of the blue" for anyone reviewing the code. p>
Finally, in Python, they are not as bad as they are in some languages and where the "do not use" speech comes from, because Python uses namespaces in a very systematic and transparent way - so a variable is never " global "with a unique name throughout the application - it is" global "only in the module where it was declared (usually a module corresponds to a single" .py "file).
For example, the proper "pi" and "e" values for math are "global variables" in the "math" module. In a C program using multiple source files, this would mean that in any file, you could suddenly use "e" as a variable containing the constant, removing it from "nothing" - and that's what makes maintaining global variables complicated - and creates such a "global variable culture should not be used". But in Python, if you want to use "e", you have to explicitly specify at the beginning of each file you are going to use it: from math import e
, or simply import math
and use math.e
in that file.
More than that, in Python, we do not properly have "variables", and more technically "names" associated with objects. In this sense, "names" are defined by the command =
which is what we read as a "variable declaration", but are also defined by the def
commands when declaring a function, class
, when we declare a class, etc ... That is: In Python all functions and classes declared in a module are also "global variables".
In% with_%, variables declared within functions are treated as attributes within objects, and these attributes can be accessed from the global scope using the name of the object / function that contains it as a reference.
If you want the global scope to have access to declared variables within functions, simply prefix the variable with the function name by declaring it and accessing it, see:
def foobar():
foobar.n = 123
foobar() # Funcao declara e inicializa a variavel 'n'
print(foobar.n) #Lendo 'n' em foobar()
foobar.n = 456 #Alterando 'n' em foobar()
print(foobar.n) #Lendo 'n' em foobar()
Output:
123
456
There are cases in which the function that declares the variable has not yet been called, and consequently, that variable has not yet been declared:
def foobar():
foobar.n = 123
print(foobar.n) # AttributeError: 'function' object has no attribute 'n'
To find out if the variable has already been declared in the scope of the function, simply test it using the native function Python
, see:
def foobar():
foobar.n = 123
# ...
if not hasattr(foobar, "n"):
print("variavel nao declarada!")
else
print(foobar.n)