Access variable in main function from other script - python

this is probably a silly question but I'm a little bit struggling to make it work :
Let's say I have two files :
script1.py :
myValue = 0
def addition():
global myValue
myValue += 1
if __name__ == '__main__':
addition()
print(myValue)
script2.py :
def getMyValue():
from script1 import myValue
print(myValue)
getMyValue()
Output : 0
I want my 2nd script to access the updated value so I can get '1' as output.
How do you think I can do it properly ?
Thanks for your replies

The variable myValue is not updated in script2.py as you don't call the addition() function by importing script1. That is due to the condition
if __name__ == '__main__' which ensures that every following logic is only executed if you run the script itself. If you import script1 into another script the condition if __name__ == '__main__' becomes False and none of the below code will run.
You could either just call addition() directly in script1, which would not be a very clean solution -
script1:
myValue = 0
def addition():
global myValue
myValue += 1
addition()
or reconsider if addition() actually needs to operate on a global variable. Be aware that globals in python are just global within a module and not across several modules, so importing both the variable and the function into script 2 would not allow you to call addition() in script2 with the expected effects. However, i would suggest making it accept a parameter like this - script1:
myValue = 0
def addition(a_value):
a_value += 1
return a_value
if __name__ == '__main__':
myValue = addition(myValue)
print(myValue)
and then call the addition function in script2, for example as follows - script2:
from script1 import *
def getMyValue():
my_new_value = addition(myValue)
print(my_new_value)
getMyValue()

Related

using variables of main file in imported file

I am using python and cannot solve the problem myself. I defined the variables(rb. data) in the 'main file' below. And I imported 'hp file' to use hotplate function. ( i611Robot, Teachdata, MotionParam,Position are included in 'A file' )
from hp import *
from A import *
def main():
rb = i611Robot()
data = Teachdata()
m1 = MotionParam(30,20,10,2,2)
position_1 = Position(100,200,100,0,0,0)
...
....
hotplate(rb)
if __name__ == '__main__':
main()
And this is the 'hp file' which is imported.
from A import *
def hotplate(rb) :
rb.motionparam( m1 )
rb.move( position_1 )
.......
But the problem is when I play 'main file', it says
File "main.py" line.., in <module>
main()
File "main/py", line ...., in main
hotplate()
File ".../hotplate.py", in line .., in hotplate
rb.motionparam( m1 )
NameError : global name 'm1' is not defined
I already asked question about how to use rb in hotplate.py and get answer that I have to put rb in hotplate(). This works well.
But another problem is that there are so many variables, parameters like rb and m1,
position_1 that will be used in hotplate.py file.
How can I use those all variables,instances,parameters in hotplate.py file.
As #Barmar already commented, functions should get their information from parameters.
Your code
What you're doing doesn't work:
def a():
myVar = "Hello"
b()
def b():
print(myVar)
if __name__ == "__main__":
a()
The function b doesn't know the variable myVar, the variable is out of scope.
Solution
What you have to do is to pass the arguments which the function needs to the function's parameters:
def a():
myVar = "Hello"
b(myVar)
def b(myArg):
print(myArg)
if __name__ == "__main__":
a()
Output
Hello
Learn about python functions here: https://www.w3schools.com/python/python_functions.asp

Can I call a function by inputting a string?

I want to make a function that can be called when the text input is equal to a command.
from os import system
from time import sleep
import ctypes
ctypes.windll.kernel32.SetConsoleTitleW('SimpleChat')
print('Hi, welcome to my basic chat engine!')
sleep(5)
system('cls')
username = input('Enter a username: ')
ctypes.windll.kernel32.SetConsoleTitleW('SimpleChat - ' + username)
system('cls')
def commands (command):
commandlist = ['/help','/clear', '/commands']
commanddict = {'/help' : 'help', '/clear' : 'clear', '/commands' : 'commands'}
for possibility in commandlist:
if command == possibilty:
commanddict[possibility]()
break
def textInput (text):
if text[0] == '/':
commands(text)
Does line 24 work to call a function? The way I am imagining it will work is that it will find the entry for the key 'possibility', and then call that as a function, but I am not sure.
If the previous code does not work, what would?
Suppose there's a function called help, clear,... in your code like this.
def help():
print("help!")
Then, the below commands function will do what you want.
Note that function can be used as value of dictionary in Python.
def commands (command):
command_dict = {'/help' : help, '/clear' : clear, '/commands' : commands}
func = command_dict.get(command)
if func is not None:
func()
else:
print("I don't have such a command: %s" % command)
I guess '/commands''s value(command function) in command_dict should be changed to another function. The program will crash if you type 'commands'.

Import module containing input/output

I have a python module file (func.py) and a unit test file (f_test.py):
# func.py
def f(x):
return x + 1
x = input("Enter x: "))
print("f(x): " + str(f(x)))
and
# f_test.py
import unittest
from func import f
class MyTest(unittest.TestCase):
def test(self):
self.assertEqual(f(1), 2)
When I run f_test.py I expect the test suite to be executed (successfully).
Instead however I see the following input:
Finding files... done.
Importing test modules ... Enter x:
If I comment out the input/output lines from func.py then I get the expected behaviour.
How do I achieve it without modifying func.py?
When you import func, all the code inside is run. Running the definition def f(x)... is what creates the function f.
You can distinguish between importing and running a file by using if __name__=='__main__'.
For instance:
# func.py
def f(x):
return x + 1
if __name__ == '__main__':
x = input("Enter x: "))
print("f(x): " + str(f(x)))
When you run func.py, __name__=='__main__' will be true. When you import it, it will be false (__name__ will be 'func' instead).
Of course, the correct answer is to modify func.py. If you absolutely, positively, won't modify func.py, then you could redirect standard input:
# f_test.py
import os
import sys
import unittest
oldstdin, sys.stdin = sys.stdin, StringIO.StringIO('7')
try:
from func import f
finally:
sys.stdin = oldstdin
class MyTest(unittest.TestCase):
def test(self):
self.assertEqual(f(1), 2)
You need to add to the bottom of f_test.py:
if __name__ == '__main__':
unittest.main()
This way the tests will be executed when the file is run (I forget this more times than I would like to admit).

Simple Python program with arguments not working

Just learning Python and spent quite some time on this. Why isn't it outputting anything when I pass arguments like this:
python new2.py Alice
Source code:
#!/usr/bin/python
import sys
def Hello(name):
if name == 'Alice' or name == 'Nick':
name = name + '!!!'
else:
name = name + '???'
print 'Hello', name
def main():
Hello(sys.argv[1])
Python doesn't implicitly call your main function. You either call it directly:
def main():
Hello(sys.argv[1])
main()
or you wrap it in an idiomatic clause to do a similar thing:
if __name__ == "__main__":
main()

how to pass arguments to imported script in Python

I have a script (script1.py) of the following form:
#!/bin/python
import sys
def main():
print("number of command line options: {numberOfOptions}".format(numberOfOptions = len(sys.argv)))
print("list object of all command line options: {listOfOptions}".format(listOfOptions = sys.argv))
for i in range(0, len(sys.argv)):
print("option {i}: {option}".format(i = i, option = sys.argv[i]))
if __name__ == '__main__':
main()
I want to import this script in another script (script2.py) and pass to it some arguments. The script script2.py could look something like this:
import script1
listOfOptions = ['option1', 'option2']
#script1.main(listOfOptions) insert magic here
How could I pass the arguments defined in script2.py to the main function of script1.py as though they were command line options?
So, for example, would it be Pythonic to do something such as the following?:
import script1
import sys
sys.argv = ['option1', 'option2']
script1.main()
Separate command line parsing and called function
For reusability of your code, it is practical to keep the acting function separated from command line parsing
scrmodule.py
def fun(a, b):
# possibly do something here
return a + b
def main():
#process command line argumens
a = 1 #will be read from command line
b = 2 #will be read from command line
# call fun()
res = fun(a, b)
print "a", a
print "b", b
print "result is", res
if __name__ == "__main__":
main()
Reusing it from another place
from scrmodule import fun
print "1 + 2 = ", fun(1, 2)
# script1.py
#!/bin/python
import sys
#main function is expecting argument from test_passing_arg_to_module.py code.
def main(my_passing_arg):
print("number of command line options: {numberOfOptions}".format(numberOfOptions = len(sys.argv)))
print("list object of all command line options: {listOfOptions}".format(listOfOptions = my_passing_arg))
print(my_passing_arg)
if __name__ == '__main__':
main()
#test_passing_arg_to_module.py
import script1
my_passing_arg="Hello world"
#calling main() function from script1.py code.
#pass my_passinga_arg variable to main(my_passing_arg) function in scritp1.py.
script1.main(my_passing_arg)
##################
# Execute script
# $python3.7 test_passing_arg_to_module.py
# Results.
# number of command line options: 1
# list object of all command line options: Hello world
# Hello world

Categories