I want to know how to pass values between modules in Python.
In generate_image.py I have:
def gerenate_image(fr,to,lat1,lon1,lat2,lon2):
output_image_name = spatial_matrix.plot_spatial_data(data_array,data_array.shape[0],data_array.shape[1],float(lon1)/10000,float(lon2)/10000,float(lat1)/10000,float(lat2)/10000,fr,to)
return()
In overlay.py, I want to use the "output_image_name",so I tried:
import generate_image
def overlay():
overlay = generate_image.output_image_name
....
but it didn't work. So how can I retrieve the value of output_image_name?Thanks.
Make your function return something.
def generate_image(fr,to,lat1,lon1,lat2,lon2):
return spatial_matrix.plot_spatial_data(data_array,data_array.shape[0],data_array.shape[1],float(lon1)/10000,float(lon2)/10000,float(lat1)/10000,float(lat2)/10000,fr,to)
Then in the other place import and call the function.
from yourmodule import generate_image
def overlay():
background = generate_image(*args) # Or what ever arguments you want.
In overlay.py:
def gerenate_image(fr,to,lat1,lon1,lat2,lon2):
return spatial_matrix.plot_spatial_data(...)
In generate_image.py:
import generate_image
def overlay():
overlay = generate_image.generate_image(...)
Related
Is there a way to make a function_a define a variable usable inside another function_b so that both are possible to import in a project ? Something like so:
Script_1
def func_a(str):
if str == 'Yes'
nb = 1
else:
nb=0
return nb
def func_b(int)
calc = (nb+int)**2
return calc
Script_2
from Script_1 import func_a, func_b
func_a('Yes')
func_b(5)
My attempt at declaring nb in Script_2 did not work as python tried to find it in Script_1. I hope this can give an idea of what I am trying to do. Also, the names of the variable are but a representation of type (strand int) I am looking for. Python is rather new to me and I am still learning. Thanks in advance.
The standard way to pass state from one function to another is for one function to return the value and for the other to take it as an argument.
# Script_1
def func_a(msg: str) -> int:
if msg == 'Yes':
return 1
else:
return 0
def func_b(na: int, nb: int) -> int:
return (na + nb)**2
# Script_2
# from Script_1 import func_a, func_b
nb = func_a('Yes')
print(func_b(5, nb))
By adding nb as an argument to func_b, we can take the return value from func_a and pass it to func_b. (Doing weird stuff with injecting data into the global namespace is technically possible, but it makes your code extraordinarily difficult to debug.)
Thanks to Amadan's suggestion, I was able to do this:
class test(object):
def __init__(self,string):
self.string = string
if string == 'Yes':
self.factor = 1
else:
self.factor = 0
def func(self, num):
calc = (num+self.factor)**2
return calc
And can be used as such in another file once saved in test.py:
from test import test
test('Yes').func(3)
test('No').func(3)
I have a function (func.py). Structure of which look like this:
database = 'VENUS'
def first_function():
print("do some thing")
def second_function():
print("call third function)
third_function()
def third_function(db = database):
print("do some other thing")
I need to import this function and used the inner defined function. But, I want to use a different key for database. Basically, I want to overwrite database = 'VENUS' and use database = 'MARS' while second function call the third function. is there any way to do this?
Just provide the database name as argument
first_function("MARS")
second_function("MARS")
So the problem here, if I understood correctly, is that the default argument for func.third_function is defined at import time. It doesn't matter if you later modify the func.database variable, since the change will not reflect on the default argument of func.third_function.
One (admittedly hacky) solution is to inject a variable using a closure over the imported function. Example:
file.py:
x = 1
def print_x(xvalue = x)
print(xvalue)
Python console:
>>> import file
>>> file.print_x()
1
>>> file.x = 10
>>> file.print_x() # does not work (as you're probably aware)
1
>>> def inject_var(func_to_inject, var):
def f(*args, **kwargs):
return func_to_inject(var, *args, **kwargs)
return f
>>> file.print_x = inject_var(file.print_x, 10)
>>> file.print_x() # works
10
So using the inject_var as written above, you could probably do:
func.third_function = inject_var(func.third_function, "MARS")
I have a python module mymodule.py:
def auth():
'''Authorize and generate a JSON file'''
return j
j = auth()
def get_value(key):
'''Takes the key and return value from JSON'''
value = j[key]
return value
I have a program where I use this module myprogram.py:
import mymodule
keys = [1,2,3,4,5]
def simple_program(keys):
# mymodule.auth() should I place it here?
for key in keys:
value = mymodule.get_value(key)
return value
So the goal is to call mymodule.auth() once, every time I run simple_program to refresh the JSON file. I don't know how to achieve this. Because myprogram.py is also a module and I call simple_program() from another .py file. So where do I place mymodule.auth()? Is it ok to place mymodule.auth() inside simple_program?
The instant you import mymodule the code below runs
j = auth()
which is why when you call mymodule.get_value() it works. This causes J to be a singleton in the global space. Everytime you import this, auth() will run again. This could be bad.
What you could do is this:
def auth():
'''Authorize and generate a JSON file'''
return j
j = None
def get_value(key):
global j
'''Takes the key and return value from JSON'''
if not j:
j = auth()
value = j[key]
return value
Now you just need to run get_value() and everything should work fine. No need to execute auth() again.
Your exact use case is a little vague (e.g. simple_program is not the main program but smth like a subroutine? and it is called several times from another py file?), but it seems to me like you should get familiar with classes. I would suggest to implement auth() as a class, e.g. like this:
class MyJson(object):
def __init__(self):
self._json = ... # do authorization and generation here and save the result as member
def get_value(self, key):
value = self._json[key]
return value
Now import and create an object of that class wherever you need it for the first time
from mymodule import MyJson
# ...
my_json = MyJson()
If you only need it to be initialized once, do that in your main program and pass the my_json object as parameter to simple_program (which should possibly also be a class). And then use it like
value = my_json.get_value(key)
I created the code below, but when I click on the click me button I get the following error message:
TypeError: 'mpfr' object is not callable
Would someone know what is wrong with the code?
import gmpy2 as g
from ipywidgets import widgets
from IPython.display import display
button = widgets.Button(description="Click Me!")
display(button)
max_precision = g.get_max_precision()
pi = g.const_pi()
g.set_context(g.context())
def set_bits_precision(decimal_precision):
bits_precision = int(decimal_precision/g.log(2))
if (bits_precision > max_precision): bits_precision = max_precision
ctx = g.get_context()
ctx.precision = bits_precision
return
def square_root(number):
return g.sqrt(number)
def circle_perimeter(radius):
return 2*pi*radius
def on_button_clicked(x):
return square_root(x)
set_bits_precision(10)
print(pi)
button.on_click(on_button_clicked(2))
button.on_click must be given a callback function. You pass the result of on_button_clicked evaluated with parameter 2 (so, literally the square root of 2) instead of passing in a function. You can use partial function evaluation to do what you want, by replacing your last line of code with:
import functools
button.on_click(functools.partial(on_button_clicked, 2))
I'm working with a code that have this appearence:
module.py:
def attribute3():
return "something3"
def attribute2():
return "something2"
def attribute1():
return "something1"
main.py:
from module import attribute1, attribute2, attribute3
def main():
return {
"attribute1": attribute1(),
"attribute2": attribute2(),
"attribute3": attribute3()
}
print main()
And i would like to know if there is any better way to create the dictionary in the main function, without the necessaty of doing "attribute: function()". I'm feeling like i'm repeating my self.
I don't have access to the module.py code, so i can't change to a Class.
I'm using Python 2.5 because this is a legacy software.
Thanks.
You could use getattr and call the arbitrary functions returned.
import some_module
def create_dict(module, names):
resp = {}
for name in names: # Iterate over an arbitrary number of arguments
# Get the function with the name provided and call it,
# setting the response as the value for the name
resp[name] = getattr(module, name)()
return resp
print create_dict(some_module, ['attribute1', 'attribute2', 'attribute3'])
I didn't test this on Python 2.5 but I don't see any reason why it wouldn't work.