I have defined some global parameters in Python (that should also be accesible from other files) and I would like to change them inside the class in which they are defined. I read quite often that one way of doing this is to use 'global' when defining the variables inside the function. However, I also read quite often that 'global' should be avoided basically as it is not good style. Now my question is what other opportunities do I have to change my variables? When just passing them to the function as arguments (this was also one suggestion) their values remain the same.
So here is my code:
from random import random
numberOfBuildings = 10
numberOfVehicles = 10
useMonteCarloMethodForScenarioCreation = True
def monteCarloScenarioGeneration(numberOfBuildings, numberOfVehicles):
numberOfBuildings_MonteCarlo = int( numberOfBuildings *random() *2 + 1)
numberOfVehicles_MonteCarlo = int(numberOfVehicles *random() *2 + 1)
if useMonteCarloMethodForScenarioCreation ==True:
numberOfBuildings = numberOfBuildings_MonteCarlo
numberOfVehicles = numberOfVehicles_MonteCarlo
monteCarloScenarioGeneration(numberOfBuildings, numberOfVehicles)
print('numberOfBuildings: ', numberOfBuildings)
print('numberOfVehicles: ', numberOfVehicles)
The value of the global variables numberOfBuildings and numberOfVehicles are not changed when the function monteCarloScenarioGeneration is called. They keep the same values that they have after being initialized (10). How can I change the global variables without using the keyword global? I'd appreciate any comments.
You should just be able to use return to change the variables outside of the function, if I'm reading this right.
As the last line of the function, put
return numberOfBuildings, numberOfVehicles
and then when calling the function
numberOfBuildings, numberOfVehicles = monteCarloScenarioGeneration(numberOfBuildings, numberOfVehicles)
Related
Goal
I am trying to write a function where one or more of the input parameters is a global variable that is updated by the function, without having to return values from within the function. I am aware I could just return a tuple or two separate values from the function, but I think updating the global variables from within the function would be another interesting method if it is possible.
Reason to do this
Updating global variables with a function is easy when the global variable is known (ie. defined previously in the python script). However, I want to define the function in a separate .py file to easily use the function within other python scripts. Therefore, I need to be able to support different variable names to update.
While this is not at all necessary, I am just interested if this is even possible.
Example Pseudocode
I'm thinking something like this:
def math_function(input_val, squared_result, cubed_result):
squared_result = input_val**2 #update the var input as the squared_result parameter
cubed_result = input_val**3 #update the var input as the cubed_result parameter
where you would input a number for input_val and then global variables for squared_result and cubed_result that the function updates with the result. It would then theoretically work like:
#Declare global variables
b = 0
c = 0
#then somewhere in the code, call the function
math_function(2, b, c)
#check the new values
print(b) #Output: b = 4
print(c) #Output: c = 8
This would allow me to use the function in different python scripts without having to worry about what order the results are returned in.
First: I am in no way advocating this.
You could use the globals builtin function to access a global variable by name:
def gtest(name,value):
globals()[name] = value
gtest('new_global','new_value')
print(new_global)
I am not advocating this too, I would like to hear everyone's thoughts, but this can be done -
my_global = [0, 0]
def my_math_func(x, g):
g[0] = x ** 2
g[1] = x ** 3
my_math_func(3, my_global)
Short example:
def Tk1():
x = 1
def Tk2():
x = 2
I want "x" to not change down the code into the subsequent variable. Can I have both "x" assigned to different values and not mess up the code within the def?
Yes a variable that is defined in the function, will always stay the same in that specific function, however if you define it outside the two functions the value can change depending on which function you call first:
a = 0
def f_a():
a = 10
return a
def f_b():
a = 4
return a
print(f_a())
print(f_b())
Will return this result:
10
4
The way you showed in your question defines the variable inside the function meaning it is local to that specific function. Note the fact it isn't a global variable.
For example: in this code, function changes when the variable changes. I would like to learn how to prevent the change in function behaviour when i change the variable. Is there some way to only get the value of the variable instead of the variable itself? Also are there any sources where I can learn more about problems like this?
a = 5
adder = lambda x: x + a
print(adder(5)) # prints 10
a = 50
print(adder(5)) # prints 55
Just like the equivalent function defined by a def statement (which is what you should be using, rather than assigning the result of a lambda expression to a name explicitly)
def adder(x):
return x + a
the name a isn't looked up until the function is called.
One way to make a function that specifically computes x + 5 when a == 5 at definition time is use a default argument value:
def adder(x, a=a):
return x + a
where the left-hand a is a new parameter (which isn't intended to be set explicitly), and the right-hand a is the value of the a in the current scope.
A better idea, though, is to define a closure, so that your function doesn't have a "hidden" parameter that can be abused.
# This is where a lambda expression does make sense: you want
# a function, but don't need to give it a name.
def make_adder(a):
return lambda x: x + a
adder = make_adder(5)
a in adder is still a free variable, but now it refers to a variable in a scope which you don't "outside" access to after make_adder returns.
I have the following snippet:
def test ():
num_sum = 0
def inner_test ():
global num_sum
num_sum += 1
inner_test()
return num_sum
When I run test() I get:
NameError: name 'num_sum' is not defined
I was expecting that the inner function would change the value of the num_sum variable defined in the outer function. Basically, I need a global variable to increment in an inner function which I may call recursively.
I noticed that this pattern works well with collections (lists, dictionaries) even if I don't define the variable as global (but pass it as a parameter to the inner function).
However, with scalar values like int this pattern seems to break. Neither defining the variable as global (as is here) nor passing it as a parameter to the inner function works as intended. Basically, the scalar variable stays unchanged. What do I need to do to get the desired behaviour with such scalar values?
you need nonlocal instead of global. your num_sum is not a global variable (will not be found in globals()). nonlocal will instruct python not to search for it in the global namespace, but in the nearest namespace. the order is LEGB: Local, Enclosed, Global, Built-in.
This question already has answers here:
Using global variables in a function
(25 answers)
Closed last month.
I'm new to python.
I don't quite understand how I need to set variables and change them within a function to be used late. My script needs to get an x and y value from a function which are determined by the size of the chart the function creates. These variable need to be passed to a print command later in the script to output html. So let's say I have global variables:
originx_pct = 0.125
originy_pct = 0.11
But these will need to change when the funtion is run...
def makeplot(temp, entropy,preq):
originx_pct = origin.get_points()[0][0]
originy_pct = origin.get_points()[0][1]
Then printed within the javascript of the html page that is written later...
print('var originx_pct = {};'.format(originx_pct))
print('var originy_pct = {};'.format(originy_pct))
The 2 variables don't change and I just don't understand what I need to do to update them and be able to print them (outside the function). I'm assuming that the function does not know about the variables so it can't change them. If I feed the function the 2 variables as arguments, how do i get the values back out for the print part of the script?
You need to use the global keyword in your function.
originx_pct = 0.125
originy_pct = 0.11
def makeplot(temp, entropy,preq):
global originx_pct, originy_pct
originx_pct = origin.get_points()[0][0]
originy_pct = origin.get_points()[0][1]
You can read more about global here.
In your function, you need to return the values. Change your makeplot to the following:
def makeplot(temp, entropy, preq):
local_originx_pct = origin.get_points()[0][0]
local_originy_pct = origin.get_points()[0][1] # the local_ in the names doesn't mean anything, it is just for clarity.
return local_originx_pct, local_originy_pct
Then, when you call the function, set your variables to its return value.
originx_pct, originy_pct = makeplot(args_and_stuff)
This is considered better practice then directly changing global variables as in ltd9938's answer. It helps to prevent accidentally messing stuff up for other functions. More reasons not to use global
You can either declare the global variables in the function with the lines global originx_pct and global originy_pct, or you can return them when you run the function. To do that, you can do
def makeplot(temp, entropy,preq):
return (origin.get_points()[0][0],origin.get_points()[0][1])
Or
def makeplot(temp, entropy,preq):
return origin.get_points()[0][0:2]
If origin.get_points()[0] has only two elements, you do just this:
def makeplot(temp, entropy,preq):
return origin.get_points()[0]
Then, in your main function, put
originx_pct, originy_pct = makeplot(temp, entropy,preq)
Although I'm not clear on why you're passing temp, entropy, and preq to makeplot, since you don't seem to be using them.