in python, how to make main args global - python

I want to access the args values in a class function in python.
For example, I wrote a sample test program below.
#!/usr/bin/env python
import argparse
class Weather(object):
def __init__(self):
self.value = 0.0
def run(self):
print('in weather.run')
if (args.sunny == True):
print('It\'s Sunny')
else:
print('It\'s Not Sunny')
def main():
argparser = argparse.ArgumentParser(
description=__doc__)
argparser.add_argument(
'--sunny', action='store_true', dest='sunny', help='set if you want sunny weather')
args = argparser.parse_args()
print('args.sunny = ', args.sunny)
weather = Weather()
weather.run()
if __name__ == '__main__':
main()
When I run it(./test.py), I get errors below.
('args.sunny = ', False)
in weather.run
Traceback (most recent call last):
File "./test.py", line 30, in <module>
main()
File "./test.py", line 27, in main
weather.run()
File "./test.py", line 10, in run
if (args.sunny == True):
NameError: global name 'args' is not defined
I tried putting 'global args' in the Weather.run function but got the same error. What is the correct method?

You can set it global by:
global args
args = argparser.parse_args()
or just pass sunny as argument to weather:
def run(self, sunny):
.....
weather.run(self, args.sunny)

Why don't you add whatever is in main() into the if statement?
#!/usr/bin/env python
import argparse
class Weather(object):
def __init__(self):
self.value = 0.0
def run(self):
print('in weather.run')
if (args.sunny == True):
print('It\'s Sunny')
else:
print('It\'s Not Sunny')
if __name__ == '__main__':
argparser = argparse.ArgumentParser(
description=__doc__)
argparser.add_argument(
'--sunny', action='store_true', dest='sunny', help='set if you want sunny weather')
args = argparser.parse_args()
print('args.sunny = ', args.sunny)
weather = Weather()
weather.run()

The two answers provided didn't match my app's design, this worked for me though:
class Weather(object):
def run(self):
if (args.sunny == True):
print('It\'s Sunny')
else:
print('It\'s Not Sunny')
def main():
global args
args = argparser.parse_args()

Related

call argparse print_help from function

i would like to call argparse print_help() from inside a function, but parser is in another function. Let's say:
import argparse
def f():
parser.print_help()
def a():
f()
def _read_args():
parser = argparse.ArgumentParser(description="my description")
parser.add_argument('-c', action='store_true')
return parser
def main():
parser = _read_args()
args = parser.parse_args()
a()
# MAIN
if __name__ == '__main__':
main()
i thought 2 solutions:
make parser global
read args in main ( not main() )
the 1 i don't really like global variables, if possible i prefer not use it
the 2 present problems if importing the module
which is the best way to achieve this?
thanks to all
If you want access to a variable inside a function, pass it as an argument.
def f(parser):
parser.print_help()
def a(parser):
f(parser)
...
def main():
parser = _read_args()
args = parser.parse_args()
a(parser)

How to execute the corresponding function according to the string variable?

As the title, I need to execute the corresponding function according to the different values of the string variable,
Choice_function is a function that needs to be optimized. If I have a lot of functions that need to be executed, using if else is more cumbersome. Is there any easy way to optimize the choice_function function?
My code is as follows:
def function1():
print('function1')
return
def function2():
print('function2')
return
def choice_function(name):
if name == 'function1':
function1()
elif name == 'function2':
function2()
return
def main():
function_name = 'function1'
choice_function(function_name)
function_name = 'function2'
choice_function(function_name)
return
if __name__ == '__main__':
main()
You can use vars to do it
code:
def function1():
print('function1')
return
def function2():
print('function2')
return
vars()["function1"]()
vars()["function2"]()
result:
function1
function2
if you want to use it in a function like choice_function, you can use globals.
def function1():
print('function1')
return
def function2():
print('function2')
return
def choice_function(name):
try:
globals()[name]()
except Exception:
print(f"no found function: {name}")
return
def main():
function_name = 'function1'
choice_function(function_name)
function_name = 'function2'
choice_function(function_name)
return
if __name__ == '__main__':
main()

How to parse arguments to a function in Python?

I've been trying to understand tutorials on how to parse arguments in Python using argparse. Is this how I would pass a command line input so I can run a function?
import argparse
parser = argparse.ArgumentParser(description='A test')
parser.add_argument("--a", default=1, help="Test variable")
args = parser.parse_args()
def foo():
command_line_argument = args.a
bar = 2*args.a
print(bar)
return
if "__name__" == "__main__"
try:
while True:
foo()
except KeyboardInterrupt:
print('User has exited the program')
That while True looks odd to me -- are you asking the reader to keep submitting inputs until they CTRL+C ? Because if so, argparse is the wrong thing to use: see Getting user input
If you intend a single argument then I'd move the parser stuff inside main, which is what gets executed when the script is run as a program as opposed to being imported.
Also, I'd pass a parameter to foo rather than the args block.
Lastly, I guess you're expecting to receive a number so you need type=int or similar.
import argparse
def foo(a):
bar = 2*a
print(bar)
return
if __name__ == "__main__":
try:
# set it up
parser = argparse.ArgumentParser(description='A test')
parser.add_argument("--a", type=int, default=1, help="Test variable")
# get it
args = parser.parse_args()
a = args.a
# use it
foo(a)
except KeyboardInterrupt:
print('User has exited the program')
So:
$ python foo.py --a 1
2
below is in working state
import argparse
parser = argparse.ArgumentParser(description='A test')
parser.add_argument("--a", default=1, help="Test variable", type=int)
args = parser.parse_args()
def foo():
command_line_argument = args.a
bar = 2*args.a
print(bar)
return
if __name__ == "__main__":
try:
while True:
foo()
except KeyboardInterrupt:
print('User has exited the program')
if you run python your-filename.py --a=2 it will print 4 until you stop the execution.

click python Cli.testing TypeError

I have 2 files:
click_example.py
import click
#click.group(invoke_without_command=True)
#click.option('--apikey', default='My key',
help="API key to use.")
#click.pass_context
def main(ctx, apikey):
"""
A CLI for live and past football scores from various football leagues.
resources are given as commands and subresources and their filters as options
"""
headers = {'X-Auth-Token': apikey}
ctx.obj['headers'] = headers
#main.command()
#click.option('--limit', '-l', help='limit number of records')
def scorers(limit):
click.echo('limit is : %s' % limit)
if __name__ == '__main__':
main(obj={})
and a test file:
test_cs.py
from click.testing import CliRunner
import unittest
from .clicksample import main
class Sample(unittest.TestCase):
def setUp(self):
self.runner = CliRunner()
def tearDown(self):
pass
def test_sample_command(self):
result = self.runner.invoke(main)
self.assertEqual(0, result.exit_code)
if __name__ == '__main__':
unittest.main()
I want to know why the test does not pass. When I run the clicksample script from the command line it works as expected but for some reason it does not exit as expected in the test. When I poke the result using pdb I get the following stats:
(Pdb) result
<Result TypeError("'NoneType' object does not support item assignment",)>
(Pdb) result.exit_code
-1
(Pdb)
You never set ctx.obj. This can fix that for you:
def main(ctx, apikey):
if ctx.obj is None:
ctx.obj = {}
...

Why can't multiprocess.Process call getattr method?

Trying to call two methods say_hello and say_world by getattr() in multiprocessing.Process, but method say_world hasn't been executed. How can I make it possible? Thanks.
# -*- coding: utf-8 -*-
from multiprocessing import Process
import time
class Hello:
def say_hello(self):
print('Hello')
def say_world(self):
print('World')
class MultiprocessingTest:
def say_process(self, say_type):
h = Hello()
while True:
if hasattr(h, say_type):
result = getattr(h, say_type)()
print(result)
time.sleep(1)
def report(self):
Process(target=self.say_process('say_hello')).start()
Process(target=self.say_process('say_world')).start() # This line hasn't been executed.
if __name__ == '__main__':
t = MultiprocessingTest()
t.report()
The parameter target expects a reference to a function as value but your code passes None to it. These are the necessary parts to change:
class Hello:
def say_hello(self):
while True:
print('Hello')
time.sleep(1)
def say_world(self):
while True:
print('World')
time.sleep(1)
class MultiprocessingTest:
def say_process(self, say_type):
h = Hello()
if hasattr(h, say_type):
return getattr(h, say_type) # Return function reference instead of execute function
else:
return None

Categories