Python functions-Global and local variables

Asked

Viewed 2,181 times

1

Is there a way to let the variable from within a (local) function go global? If not, what way can we declare a global variable?

  • You declare the variable outside the function and inside the function you declare global in front of the variable. However the use of global variables is not advised in large projects because it becomes dangerous its accidental modification.

  • 1

    And why would you do that? Gambiarra da grossa, mount something better that does not need it.

3 answers

3

Yes - Simply declare the variable as global at the start of the function:

def a():
   global b
   b = "teste"

a()
print(b)

(prints "test")

The keyword nonlocal can be used in functions declared within other functions (nested), and similarly allows access to and change variables in functions, "external" - but cannot be used in the same way as global to declare a variable that does not exist in the scope of the external function, since there may be more than one external 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 is also interesting to note that there is a very large culture of "global variables are bad" and "are gambiarra" - but this is not the case in Python - and I already clarify this.

Before however, it is worth noting that if you are going to use a global variable, it is practical, yes, declare it out of functions, at the beginning of the file, so that it is visible. The use of the keyword global in the functions allows it to be changed in the same way as if it were declared for the first time in a function - but this avoids surprises of the variable appearing "out of nowhere" for those who are reviewing the code.

Finally - in Python they’re not as bad, as in some languages and where the "don’t 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 across the application - it’s "global" only in the module where it was declared (as a rule, a module corresponds to a single file ". py").

For example, the very values "pi" and "e" of mathematics are "global variables" in module "Math". In a C program using multiple source files, this would make any file, you could suddenly use "and" as a variable containing the constant, taking that out of "nothing" - and that’s what makes maintaining global variables complicated - and creates this culture of "global variable should not be used". But in Python, if you want to use the "e", you have to make it explicit at the beginning of each file in which you will use it: from math import e, or simply import math and use math.e in that file.

More than that, in Python, we don’t exactly have "variables", and more technically "names" associated with objects. In this sense, the "names" are defined by the commando = which is what we read as a "variable declaration", but are also defined by the commands def when we declare a function, class, when we declare a class, etc... That is to say: in Python all functions and classes declared in a module are also "global variables".

  • Thank you very much for the explanation, I will see if it fits my code... Now I will explain why this "gambiarra"... I’m making a mini registration system using only Pyhton as language (I know it’s wrong, but I’m still a little short of time to study others) My system so far has an interface using the Tkinter module and has a database, making the connection with Sqlite3... But I’m having to do several tricks, because the screen that collects the data is in a function.

  • In this same function has a button that when clicked, calls another function, which is the one that will transport this data to the database, but as the data are within the window function() they are as local variables (I think), only know that when collecting the data, the shell says that the variable was not defined, so I thought it was happening to the fact that it is in a function and its transport is in another function. Result: I’m breaking my head too much to make a system using gambiarras and a language... I’ll see if I can fix this, giving up is the last option..

  • Global variables are with "global". The problem you are describing probably looks better with attributes on an object. Ask another question, describing your problem, not what you think the solution is, and put your code - then people can guide you in a good design for the code. As it stands, they are praising unnecessary complications because of the way the question was asked (instead of saying how to declare global variables, which is trivial, thinking of ways to "promote" a local variable to global, which is juggling with little real utility.)

2

There she is, returning her.

There are defined and "rigid" scopes because it’s the best environment - or at least it makes life much easier for the developer, because the smaller its scope, the easier it is to manage its variables. Having functions that alter the global scope are bad for maintenance, greatly impair the readability of the code and have generated many WTF in your project (surely there are many other implications).

But he’s not a hopeless case. Like you, many others before have felt the need to return to the external scope some variables defined in the external scope. Out of this came the return - maybe not exactly like this, but for now it’s a cute little story.

That is, if you define foo inside 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()

Becoming explicit as foo appeared in this scope, without magic gambit.

But then you ask me: Anderson, but what about your need to return several function variables? The answer is simple: refatore. Having this need is a clear indication that the way you are doing it is not the simplest and you need to redo it. If you need to return several variables, they are somehow related to each other and would probably be better organized within a class/object. But what if they don’t have any connection to each other, wouldn’t the class be weird? Yes, but if there is no relationship between the variables, they should not be in the same function.

Like everything else in nature, you must seek in your code the lowest energy state. It is not enough just to work, it needs to work and not create problems in the future. The less you have to come back for maintenance on this piece of code, the better, so do something consistent.

  • Sorry - plenty of text, and a lot of explanation, but it’s just wrong. There is the keyword "global".

-2

In Python, 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 reference.

If you want the global scope to have access to the variables declared within functions, just prefix the variable with the name of the function when declaring it and when accessing it, see only:

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()

Exit:

123
456

There are cases in which the function declaring the variable has not yet been called, and consequently, such variable has not yet been declared:

def foobar():
    foobar.n = 123

print(foobar.n) # AttributeError: 'function' object has no attribute 'n'

To know if the variable has already been declared in the scope of the function, simply test it by means of the native function hasattr(), look at you:

def foobar():
    foobar.n = 123 

# ...    

if not hasattr(foobar, "n"):
    print("variavel nao declarada!")
else
    print(foobar.n)
  • Extensive answer, with legal things, but wrong. Sorry , -1.

  • Wrong in what sense? Could I explain? I don’t live by praise alone.

  • 1

    yes - is wrong because the keyword "global" does exactly what is being asked, and you don’t even mention it in the answer.

  • Also, the solution you present of using the function itself as namespace is ingenious, but it’s not a common practice - if it were in a code review, I would suggest using a class and putting this "function attribute" as an instance attribute.

  • It was on purpose that I avoided using the word global in my answer: When you use the word global within a function, the affected variable becomes part of only and only the overall scope and no longer belongs exclusively to the scope of the function. Proof of this is that foobar.n can cohesite with n (in the global scope), that is, in different memory spaces. The question implies that it is the outside (global) scope that is intended to access the variables declared within the scope of the function. It was from these premises that I drew up my answer. Obrg for the return.

  • I understand your reasoning now. But without even managing global in his reply, which is "There should be one-- and preferably only one --obvious way to do it." for global variables in Python - and what other people will want to know when they fall here with doubt, I personally do not consider the answer to be correct.

  • (stop for the 10K, by the way!)

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.