How to pass on variable to function in different script file - python-2.7

Ich have one python file where I declare my variables and a second file containing more functions (in this example only one function). I can't seem to figure out how to pass on the variables from one.py to two.py.
one.py:
import two
a=1
b=2
c=3
dict={'ONE':a,'TWO':b,'THREE':c}
two.py:
def f():
d=a+b+c
return d
two.f() should return:
6
Thanks in advance
EDIT:
It's working fine in the command line in the mean time. But for some reason doesn't want to work when I run the script in Abaqus. It says:
count=two.f(my_dictionary)
AttributeError:'Module' object has no attribute 'f'

First of all create a module to make 'import two' work.
- Create a directory and put a blank init.py file there, two.py and one.py.
Your two.py should be:
def f(x):
return x['ONE']+x['TWO']+x['Three']
Your one.py should be:
import two
a=1
b=2
c=3
my_dictionary={'ONE':a,'TWO':b,'THREE':c}
two.f(my_dictionary)

Related

Call functions within a python script and pass arguments using command line

I have a script named first_code.py
The code in the script looks like
def function1(param1):
return var1
def function2(param1):
return var2
def function3(param1):
return var3
I want to execute the script first_code.py from the windows command like and pass the value of the param1 such that: all the functions get executed or if I want to execute a specific function say function2.
How can I do that?
You could use something like this to have a more generalized way to call a function the takes 0-* params :
if __name__ == '__main__':
print (len(sys.argv))
params = []
if len(sys.argv) > 2:
for x in range(2, len(sys.argv)):
params.append(sys.argv[x])
if len(params) > 0:
globals()[sys.argv[1]](*params)
else:
globals()[sys.argv[1]]()
If your script 'getstuff.py' included a function named 'getSomething(forWho, fromWho)' it
can be called:
python getstuff.py getsomething "Ray" "Steve"
Can take as many parameters as you want.
Just include the snippet in you script.:>)
The arguments you specify in command line are kept in sys.argv
you should add the following lines in the bottom of the code:
print function1(sys.argv[1])
print function2(sys.argv[1])
print function3(sys.argv[1])
please note sys.argv[0] is the script name.
If you want to specify the functions to be run add more arguments, they will be in sys.argv[2], sys.argv[3] etc'

Use Python command line argument as function names and function values

Related to this question Command line arguments in python.
With the SYS module, how can I use a command line argument as a function name and function value, within my code - without importing some other module?
I'd like a solution that uses sys only. Also, please no variable-length params answers. Those are confusing. Assume that just the function name and one function variable are specified at the command line.
import sys
def reversal(aaa): return aaa[::-1]
a = sys.argv[1]
b = sys.argv[2]
print a(b)
At the command line
cpu_location$ python blah.py reversal 'abcdefg'
Traceback (most recent call last):
File "blah.py", line 8, in <module>
print a(b)
TypeError: 'str' object is not callable
I want to know how to make sys.argv[1] be considered a function name, thereby calling the function I have defined.
The other posts I see on this are a mash up of:
- dealing with C/C++ and adding some other module
- not using sys at all
- using the argv items as values for functions, and names of other files, instead of names of functions
Better than the eval solution would be:
a = globals()[sys.argv[1]]
a(b)
globals() returns a dictionary mapping global variables names to those global variables. So globals()['reversal'] evaluates to the reversal function.
It's safer than the eval function. With your approach you could do something like:
python blah.py 'lambda x: x+"hi"' foobar
Which would print foobarhi, which is unexpected because that's not a function name.
2 hours later, I find the answer. I think it's worth it to post it here in a very simple fashion.
Basiclaly there is no "function" data type in Python, but someone did mention a function eval, which is built-in. Execute python commands passed as strings in command line using python -c (No -c is needed for my own example)
The solution, is to change
a = sys.argv[1]
to
a = eval(sys.argv[1])
This will make the passed in word, reversal, be evaluated. It will evaluate to a function. Then the a(b) call will be a perfect call of a function on a string, like how it's defined. Output will be like:
cpu_location$ python blah.py reversal unquoted
detouqnu
cpu_location$ python blah.py reversal 'withquotes'
setouqhtiw
use google module: fire
pip install fire
Here's a simple example:
import fire
class Calculator(object):
"""A simple calculator class."""
def double(self, number):
return 2 * number
if __name__ == '__main__':
fire.Fire(Calculator)
Then, from the command line, you can run:
python calculator.py double 10 # 20
python calculator.py double --number=15 # 30

Why can't I access par inside the function even if I use the keyword global in the following python program?

I am trying to access the variable par (declared inside the main module) inside the function func(). But I am getting the exception 'global name par is not defined'. What am I doing wrong?
Main.py
if __name__ == '__main__':
import Second as S
par = {1 : 'one'}
S.func2()
def func():
global par
print('In func')
print(par[1])
Second.py
import Main as M
def func2():
M.func()
If you import the file, then the value of __name__ wont be "__main__" and the par dict never gets defined. (__name__ will instead be the name of the module, in this case "temp")
if __name__ == "__main__": is used shield bits of code designed only to run when the script is run directly (ie python temp.py). If the file is imported, then that if condition will evaluate False.
I think the root of your confusion, is that normally if multiple python files import the same file they enter sys.modules as the same entry/object so they have the same namespace. However the main script that's invoked gets a special name (__main__) so if you happen to import it, python doesn't see it and creates a new python module object.
import sys
if __name__ == '__main__':
import Second as S
par = {1 : 'one'}
S.func2()
def func():
print(sys.modules["__main__"]) # here par is defined
print(sys.modules["Second"].M) # here it isn't
global par
print('In func')
print(par[1])
Your first example ran just fine on repl.it, but you probably did not run it as the main file. Your new example shows that you source the file in your second script, so __name__=="__main__" evaluates to false, ergo:
par does not get initialized!
Why do you include the if branch in the first place?
By the way, you do not need the global declaration if you just want to print par. Global is only required if you intend to change the value.

how import statement executes in python?

I read about about import statement in pydocs. It says it executes in two steps.
(1)find a module, and initialize it if necessary; (2) define a name or names in the local namespace (of the scope where the import statement occurs). The first form (without from) repeats these steps for each identifier in the list. The form with from performs step (1) once, and then performs step (2) repeatedly.
I understood some bits of it, but its still not clear to me completely.I am mainly confused about initialization step and at last it says about repeating some step.The only thing which i understood is that if we use say for example:
import sys
in this case if we use functions of this module in our script we need call them using sys.fun_name(). As the functions weren't made available locally using this importstatement.
But when we use
from sys import argv
We can simply use argv function as it makes it available local for out srcipt.
Can someone please explain me its working and also let me know my understanding is correct or not.
Even i tried to import one of the my script into another script and it gave some strange result which i know have something to do with first step of import statement,(initiallization)
##### ex17.py #####
def print_two(*args):
arg1, arg2 = args
print "arg1: %r, arg2: %r" %(arg1, arg2)
def print_two_again(arg1, arg2):
print "arg1: %r, arg2: %r" %(arg1, arg2)
def print_one(arg1):
print "arg1: %r" %arg1
def print_none():
print "I got nothing."
print_two("Gaurav","Pareek")
print_two_again("Gaurav","Pareek")
print_one("First!")
print_none()
####### ex18.py ######
import ex17
ex17.print_none()
The output which i am getting when executing ex18.py is as below
arg1: 'Gaurav', arg2: 'Pareek'
arg1: 'Gaurav', arg2: 'Pareek'
arg1: 'First!'
I got nothing.
I got nothing.
why is it like this. It should only print I got nothing once.
It prints "I got nothing." twice because the function print_none is being invoked twice. Once when loading the ex17 module (since it's imported in ex18) and once when it's called in the ex18 module. If you don't want the function calls in ex17 to execute but only the function defs to be loaded, then you may write them as follows
## in ex17.py
if __name__ == '__main__':
print_two("Gaurav","Pareek")
print_two_again("Gaurav","Pareek")
print_one("First!")
print_none()
Now this code will only be executed if it's run as a script ie. $ python ex17.py but not when it's imported into some other module. More about __main__ here
About the excerpt from the docs, it simply says how the two import forms differ. Step 1 is responsible for finding and initializing the module and step 2 for adding the names to the local namespace. So in case of,
import sys
both step 1 and 2 will be executed once. But in case of,
from sys import argv, stdout
step 1 will be executed just once, but step 2 will be executed twice as it needs to add both argv and stdout to the local namespace.

How to redirect from a python script to another scripts taking user input

I have 2 python scripts Script1.py and Script2.py respectively. I create another script called Value.py in which I want to take a user input as either Script1 as a string which would run Script1.py or Script2 which would run Script2.py.
Please can someone help me out in making this short script.
Thanks
Rather than running the scripts separately, you should encapsulate their contents into a function and either:
Put all three functions into one .py file (if they're short); or
import the two existing functions into value.py (if they're long).
Then value simply looks like:
from Script1 import func1 # only for option 2
from Script2 import func2 # only for option 2
def value():
...
if user_input == "Script1":
func1()
else:
func2()
def func1(): # only for option 1
...
def func2(): # only for option 1
...
value() # call value