How to pass a variable as a parameter to a function?
This is my code
def hello (arg):
global my_name
my_name = "tarek"
print("my name is " + arg)
hello(my_name)
This should print
my name is tarek
but it doesn't, giving me a NameError, although I declared the variable my_name as global.
Well it works well if I declared the variable outside the function, but why is it not working when declaring the variable inside the function?
You have to define your global variable outside of your function, then you don't need to define it again in the function. Following code will print what you want:
my_name = "tarek"
def hello(arg):
print("my name is " + arg)
hello(my_name)
There is no variable my_name until the function is called so there is nothing to pass into the function, giving the error.
Define the variable outside the function, then declare it global inside the function, if you must.
If you want my_name to be global you don't need to pass it into the function. Just declare and assign it outside the function, then declare it global inside.
Passing parameters is usually done because you want it to be local to that function, then we usually return it back after its been worked on. Compartmentalising you code helps when debugging.
Nothing within hello() can make my_name exist by the time hello()is called.
Your variable declaration is scoped to inside the method (a closure), and that closure is not evaluated until you invoke it, at which point you get an error because the variable does not exist in that context.
If I understand correctly, it would seem you want to do this
def hello (arg):
global my_name
my_name = arg
print("my name is " + arg)
hello("tarek")
Related
For example if I write
a=1
def func():
return a
func()
It will return 1. Is this normal behavior? Are variables supposed to act in a global way in python?
If you create a variable with the same name inside a function, this variable will be local, and can only be used inside the function. The global variable with the same name will remain as it was, global and with the original value.
That is the way python language works !
I have read Cannot change global variables in a function through an exec() statement?, but this is not my case.
When i run test(), it raises exception UnboundLocalError: local variable 'var' referenced before assignment, it looks like exec('global var', globals()) doesn't work.
var = 1
def test():
exec('global var', globals()) # The effect it achieves is different from `global var`, why?
var += 1
test()
print(var)
But if i change the function to the following, it worked:
def test():
exec('global var', globals())
exec('var += 1', globals())
I don't know why, can anyone explain?
The following quote from the language reference (section "Simple statements") seems relevant:
Programmer’s note: global is a directive to the parser. It applies only to code parsed at the same time as the global statement. In particular, a global statement contained in a string or code object supplied to the built-in exec() function does not affect the code block containing the function call, and code contained in such a string is unaffected by global statements in the code containing the function call. The same applies to the eval() and compile() functions.
I.e, in your first version, var is still local to the function.
'global var' only has meaning within the context of the dynamically created program (DCP).
Consider these two options for incrementing var. They may make it more obvious what's going on.
exec('var += 1', globals())
...or...
exec('global var\nvar += 1')
In the first case the Python runtime finds var because you passed the dictionary of globals to exec(). In the second case, you qualified var with 'global' so the runtime knows where to look. Note therefore that in the second case there's no need to pass globals()
I am a beginner in python.
I am not understanding why about
assign after define global variable : valid
valid but define and assign global variable at once : not valid.
As for example:
def Test():
global a=15
Test()
print(a)
Is invalid while:
def Test():
global a
a=15
Test()
print(a)
Is valid
The global statement syntax is global <name> and just tells the interpreter that you are working with a variable from globals() instead of locals() for the current scope/frame. It really just tells Python where to grab the variable, and doesn't support assignment.
The global keyword tells your interpreter that a variable is a global one. Let's say you have this code:
a = 10
def p():
a = 20
print('This is a local:', a)
print("a is unchanged:", 10==a)
def q():
global a
a = 40
print('This is the global:', a)
print("a has changed:", 40==a)
Remember, the global only tells your interpreter that "There's this variable outside your local variables" when it is called inside functions. Therefore, you cannot assign a value to a variable that you are calling as global in one line.
I'm new to python as well, so I suppose I'll work this out with you! It looks like it indicates a syntax error at the = sign in line 2. It works in the second example because you declared the variable separately on a new indented line below global? So I'm guessing the first example won't work because the variable is declared along with global?
#Test
def test():
test1 = input("Type something: ")
test()
print(test1)
print(test1)
NameError: name 'test1' is not defined
'test1' is not defined
This is bothering me. I'm learning python and trying to write a small game for practice, and it seems that variables that are declared in a function don't carry over. Is there a way to get by this? Am I not supposed to use test() to close the function? Or should I figure out and use a class instead? Or perhaps is it just a quirk of python? Thanks for any help.
By default, all the names assigned inside a function definition are put in the local scope (the
namespace associated with the function call). If you need to assign a name that
lives at the top level of the module enclosing the function, you can do so by declaring
it in a global statement inside the function. If you need to assign a name
that lives in an enclosing def, as of Python 3.X you can do so by declaring it in a
nonlocal statement.
Read this: https://docs.python.org/3.4/tutorial/classes.html#python-scopes-and-namespaces
You need to return the value and store the returned value to print it.
def test():
test1 = input("Type something: ")
return test1
a = test()
print(a)
In general, functions should rely on arguments and return values instead of globals.
def test():
test1 = input("Type something: ")
These two lines define a function called test. When test is called (test()), the line inside will be run. The line inside assigns input to the variable test1. But test1 is scoped to the test function -- the name test1 only exists inside the function, so once the function ends, the name disappears.
Functions are called to produce output (or side-effects, but in this case, output). You do that by using the return keyword to end your function and return a variable. In this case, you could do return test1 inside your function (technically you could just to return input(...) directly too, and skip the creation of the variable entirely).
test()
This calls the function. You can do this at any time after the function is defined; you don't need to do it to "close" the function.
If you modify your function to return a value, then you'll need to do something with the return value on this line. Something like result = test(). That assigns the return value of test to the result variable.
print(test1)
This isn't working because test1 only exists inside the function namespace, and you are calling this line outside of the function namespace. If you've made the changes I suggested above, you can do print(result) instead.
I keep getting an unbound local error with the following code in python:
xml=[]
global currentTok
currentTok=0
def demand(s):
if tokenObjects[currentTok+1].category==s:
currentTok+=1
return tokenObjects[currentTok]
else:
raise Exception("Incorrect type")
def compileExpression():
xml.append("<expression>")
xml.append(compileTerm(currentTok))
print currentTok
while currentTok<len(tokenObjects) and tokenObjects[currentTok].symbol in op:
xml.append(tokenObjects[currentTok].printTok())
currentTok+=1
print currentTok
xml.append(compileTerm(currentTok))
xml.append("</expression>")
def compileTerm():
string="<term>"
category=tokenObjects[currentTok].category
if category=="integerConstant" or category=="stringConstant" or category=="identifier":
string+=tokenObjects[currentTok].printTok()
currentTok+=1
string+="</term>"
return string
compileExpression()
print xml
The following is the exact error that I get:
UnboundLocalError: local variable 'currentTok' referenced before assignment.
This makes no sense to me as I clearly initialize currentTok as one of the first lines of my code, and I even labeled it as global just to be safe and make sure it was within the scope of all my methods.
You need to put the line global currentTok into your function, not the main module.
currentTok=0
def demand(s):
global currentTok
if tokenObjects[currentTok+1].category==s:
# etc.
The global keyword tells your function that it needs to look for that variable in the global scope.
You need to declare it global inside the function definition, not at the global scope.
Otherwise, the Python interpreter sees it used inside the function, assumes it to be a local variable, and then complains when the first thing that you do is reference it, rather than assign to it.