This question already has answers here:
Short description of the scoping rules?
(9 answers)
Closed 6 years ago.
So I am learning the difference between global and local vars in Python 2.7 and as per my understanding
local var is one that is defined within a function and
globar var is one that is defined outside of the function.
I created this simple function to test how these local and global vars work when used in combination
def f():
global s
print s
s = "Python is great."
print s
Before I ran the function, I declared the global s
s = "I love python!"
f()
The output was:
>>> f()
I love python
Python is great
I understand till this part, but what I don't understand is, when I call the run a print s outside the function, why is it printing the local variable instead of the global one. Does this mean that the global var s is used once and discarded?
>>> print s
Python is great
can someone please explain this?
... what I don't understand is, when I call the run a print s outside the function, why is it printing the local variable instead of the global one.
There is no local s within the function. The global s statement causes the Python VM to use the s in the global scope even when binding it.
You declared s to be a global in the function, overriding the default behaviour, by using the global s statement. Because s is now a global, and you assigned a new value to it, that change is visible globally.
Related
I would like to use RInside in a function that is NOT the main function in my c++ program. After debugging, I found out that the function works for the first round and I get the output as expected but when it is called for the second time my program stops and I get the error message "R is already initialized". Can anybody help me to have a workaround to overcome this issue?
please see below a simple example to clarify that.
I need to call mainR() function from a function(my_func) that is also NOT the main function.I am actually dealing with a bit complex program so my_func will be also called multiple times, which made initializing RInside useless..
Sorry, the code doesn't look realistic but I just wanted to simplify and clarify my question.
#include <RInside.h>
void mainR()
{
RInside R; // create an embedded R instance
R["txt"] = "Hello, world!\n"; // assign a char* (string) to 'txt'
R.parseEvalQ("cat(txt)"); // eval the init string, ignoring any returns
}
void my_func()
{
mainR();
mainR();
.
.
}
It would appear (I am not an expert on RInside) that an application must have no more than one RInside object created over the course of an application's lifetime. This corresponds to C++'s concept of "static storage duration". When a variable is defined in the main function, the difference between "automatic" (the default) and "static" duration is usually insignificant, but it is highly significant for a function called more than once.
Adding the keyword static indicates that a variable is to have static storage duration.
static RInside R; // create an embedded R instance
This has two effects on a variable defined inside a function. First, the object is not destroyed when the function ends. Second, the object is not re-initialized when the function is called again. (It is still initialized when the function is called the first time.) This avoids the error where R was initialized twice. However, it also comes with a caveat—the object retains state between function calls. One must assume that the RInside object might have been used earlier, even at the beginning of mainR().
I have a nested if in Lua. I have a variable inside the second if layer that I want to use in the first layer.
The variable is npcSpecimen.
if conditions then
local npcType = util.pickRandom(self.npcTypes)
local npcSpecimen = ""
if npcType == "spacebandit" then
local npcSpecimen = util.pickRandom(self.npcSpecies)
else
local npcSpecimen = util.pickRandom(self.npcSpeciesMutant)
end
local npcId = space.spawnNpc(spawnPosition, npcSpecimen, npcType)
end
If written this way, npcSpecimen will remain empty because the variable set within the if npcType remains only within that chunk. So to alleviate this, I could use global variable instead:
if npcType == "spacebandit" then
npcSpecimen = util.pickRandom(self.npcSpecies)
else
npcSpecimen = util.pickRandom(self.npcSpeciesMutant)
end
However according to the documentation, using global variable isn't the best practice and it's slower.
So what would be the best way to approach this so I could pass npcSpecimen to npcId?
Technically the answer is no, you can't use a local variable outside its scope, that's the whole point of local variables. However, you can just change the scope of the variable by declaring it outside of the block where you're using it:
local foo
if io.read() == "hello" then -- Just a dumb example condition :)
foo = "hello" -- This is not a global, as it was declared local above
end
print(foo)
However, note that the the following doesn't work, or, more precisely, doesn't do the same as the above:
local foo
if io.read()=="hello" then
local foo = "hello" -- This is another local
end
print(foo) -- This will *always* print nil
General CS question because I was surprised by behavior of let in Netlogo.
If I declare a variable from within an if statement per below, is it common for the scope of that variable to be limited to that if statement?
I thought scope generally referred to functions rather than constructs like a loop or if statement. How common is that?
if x > y :
int i = 2
else:
int i = 3
print(i)
would return: "error: (i) does not exist"
I´m not sure, if this answers your question, but the Netlogo Programming Guide on local variables, created with let, states:
Local variables
A local variable is defined and used only in the context of a
particular procedure or part of a procedure. To create a local
variable, use the let command. If you use let at the top of a
procedure, the variable will exist throughout the procedure. If you
use it inside a set of square brackets, for example inside an “ask”,
then it will exist only inside those brackets.
to swap-colors [turtle1 turtle2]
let temp [color] of turtle1
ask turtle1 [ set color [color] of turtle2 ]
ask turtle2 [ set color temp ]
end
The same is true if a local variables is created within an if or ifelse statement. Therefore if you want to use the variable later on, than declare it before and outside the ifelse statement with let. Than assign the value with set within the ifelse statement.
I would appreciate if anyone could elaborate about the variable scopes in c++ addons of node js. For example, I have initialized some global variables in the addon (c++ file) like "int size" or something like this. so when I call the function in that addon it doesn't reinitialize the value. in fact if I assign something in some function "size = 27" and then after some time I call another function of that addon it will see size equal to 27. so when is addon stack deallocated and global variables reinitialized in C++ Addons?
Thanks,
I have several functions in a program I'm writing that use a value I need to calculate with a very slow function. This value will change every time the program is rerun, so I can't just store a static value. Below is an example.
void this_gets_called_frequently()
{
static int value = slow_function();
//do stuff with the above value
}
My main problem here is not one of the program not working, rather of neatness. I don't really want to initialise a global variable and store the value in that, since it is not going to change once calculated. Would using the static keyword in the manner shown above only call the function above to be calculated once? Would a const keyword added in there help?
Thanks everyone, this was answered perfectly!
Yes, an initialization of local static variable will happen at most once (although I recall some compiler versions could have problems with multithreading here).
const is not required, in this case it's mostly a matter of readability and taste.
Would using the static keyword in the manner shown above only call the function above to be calculated once?
Yes, on the first invocation of this_gets_called_frequently
Would a const keyword added in there help?
No. But add const for documentation value.
Use may use the thread local variables from C++11, if they are available in your compiler. If you are on Windows, you can use similar TlsAlloc API. It is there since the dawn of Win32.