Python: assigning variables from function(*args) using argparse - python-2.7

I'm trying to assign my arguments from argparse to variables. I have two scripts one is the parser and the other is a module. When I try to assign a variable I get a tuple object has no attribute error. Any guidance would be appreciated.
def main():
parser = argparse.ArgumentParser(description='A simple front end script interface')
subparsers = parser.add_subparsers(help='(run various listed scripts..)', dest='mode')
add_pyrr_command_options(subparsers)
args = parser.parse_args()
if args.mode == "pyrr":
pyrr.parse_cmds(args)
else:
parser.print_usage()
pyrr.py
def parse_cmds(*args):
print(args)
pass
(Namespace(mode='pyrr', plugin_name='ntuser', reg_loc='/user/home', rip_loc='/user/some'),)
When I try to assign a variable via researched methods (e.g. arg.plugin_name) I get a AttributeError: 'tuple' object has no attribute 'pyrr'

So args is a Namespace object
Namespace(mode='pyrr', plugin_name='ntuser', reg_loc='/user/home', rip_loc='/user/some')
And as your 1st script shows you can use args.mode.
In (with corrected indent)
def parse_cmds(*args):
print(args)
pass
args is a tuple (because of the *args), e.g. (Namespace(...),). With plain args you could continue to access mode with:
def parse_cmds(args):
args.mode
Another option is to pass a dictionary via **kwargs
def parse_cmds(**vargs):
# vargs is a keyword dictionary
parse_cmds(vars(args)) # converting namespace to dictionary
I think you are on the right track. You just to need to distinguish between namespace object, dictionaries, and tuples.
In your examples 'pyrr' is the string value of args.mode, and also the name of the imported pyrr.py module.

Related

Python argparse argument that is python keyword

I want to have a python command line argument --lambda, but I can't access it as lambda is a python keyword.
import argparse
p = argparse.ArgumentParser()
p.add_argument('--lambda')
args = p.parse_args()
print args.lambda
I get:
print args.lambda
^
SyntaxError: invalid syntax
How can I do this?
You can add a different name for the attribute with dest e.g.
import argparse
p = argparse.ArgumentParser()
p.add_argument('--lambda', dest='llambda')
args = p.parse_args()
print args.llambda
argparse uses hasattr and getattr to set values in the Namespace. This allows you to use flags/dest that are not valid in the args.dest syntax. Here the problem is with a restricted key word. It could also be a string with special characters. So getattr(args, 'lambda') should work.
vars(args) creates a dictionary, allowing you to use vars(args)['lambda'].
But changing the dest is a cleaner solution. That's part of why that parameter is allowed.
(For a positional argument, choose a valid dest right away.)

selenium python: what is 'lambda' in webdriverwait.until statements

I'm learning selenium webdriver with python and came across 'lambda' in following line of code. The author did not explain the use of lambda here:
search_button = WebDriverWait(self.driver, 10).until(lambda s:s.find_element_by_name("btnG"))
search_button.click()
I've read about lambda and it says lambda creates functions on the fly and some say its used to return expression. So now I'm confused and not sure exactly what difference does it make here.
In python functions are objects so you can pass them as parameters to other functions. The only thing is if you pass a function with () you call that function at the same time. So it's possible to pass functions which do not take any arguments so it can be called inside the function you passing it to later on. But if you need to pass parameters to the function while you are passing function itself you need to wrap it up in lambda so that it's called only when it's needed.
Edit
To answer the question how it gets s value. If you look into the source here doctoring explains it all:
"""Calls the method provided with the driver as an argument until the
return value is not False."""
Actual code is self explanatory as well:
def until(self, method, message=''):
screen = None
stacktrace = None
end_time = time.time() + self._timeout
while True:
try:
value = method(self._driver)
if value:
return value
except self._ignored_exceptions as exc:
screen = getattr(exc, 'screen', None)
stacktrace = getattr(exc, 'stacktrace', None)
time.sleep(self._poll)
if time.time() > end_time:
break
raise TimeoutException(message, screen, stacktrace)

Passing an argument to main that calls a function in python

I'm trying to pass arguments to my python script using argparse and consequently call functions. Any ideas where I might be going wrong?
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('-d','--d', dest='action', action='store_const',const=do_comparison,
help="Diff the current and most recent map file memory information)")
options = parser.parse_args()
return options
def do_comparison(parsed_args):
# do things
def main(args):
options = parse_args()
if __name__ == '__main__':
sys.exit(main())
In my comment I missed the fact that you are using store_const and const=do_comparison. So you are trying some sort of callback.
options from parse_args is a argparse.Namespace object. This is a simple object, similar to a dictionary. In fact vars(options) returns a dictionary.
When main is run (with -d), options.action will be set to the const, a function. But remember, in Python, functions are first class objects, and can be set to variables, etc just like numbers and strings. To be used the function has to be 'called'.
options.action()
should end up calling do_comparison. Actually since that function requires an argument, you should use
options.action(options)
or some other way of providing a varible or object to the function.
Of course you'll have to be careful about the case where you don't specify -d. Then options.action will have the default value (e.g. None). If the default isn't a callable, then this call will produce an error.
The argparse documentation illustrates this kind of action in the section dealing with subparsers (subcommands). I vaguely recall a tutorial that set an argument value to functions like add and multiply, creating a simple arithmetic expression evaluator.
Usually the values in the Namespace are strings, or numbers, and to use them you test for string equality. e.g.
if options.action is None:
# default action
elif options.action == 'print':
print(options)
else:
do some other backup or error
A callback kind of action is possible, and may be convenient in some cases, but it isn't the usual arrangement.
You asked about using successfully store a string following the -d, to be used as the function arg with:
parser.add_argument('-d','--d', dest='action', dest='function_input', action='store_const', const=diff_map)
A 'store_const' action does not take an argument (in effect nargs=0). It's more like store_true. In fact store_true is just a store_const with has default=False and const=True.
What you need is another argument, whick could occur either before or after the -d. argparse tries to be order flexible.
Here's a simple script with a callable argument, and flexible positional argument.
import argparse
def action1(*args):
print 'action1',args
def action0(*args):
print 'action0',args
parser = argparse.ArgumentParser()
parser.add_argument('-d', dest='action', action='store_const', const=action1, default=action0)
parser.add_argument('args', nargs='*')
args = parser.parse_args()
args.action(args.args)
resulting runs
1238:~/mypy$ python stack32214076.py
action0 ([],)
1238:~/mypy$ python stack32214076.py one two three
action0 (['one', 'two', 'three'],)
1238:~/mypy$ python stack32214076.py one two three -d
action1 (['one', 'two', 'three'],)
1239:~/mypy$ python stack32214076.py -d one two three
action1 (['one', 'two', 'three'],)
1239:~/mypy$ python stack32214076.py -d
action1 ([],)
TO make -d value perform some action on value, try:
parser.add_argument('-d','--action')
The default action type stores one value (e.g. action='store', nargs=None)
args = parser.parse_args()
if args.action: # or is not None
do_comparison(args.action)
If -d is not given args.action will have default None value, and nothing happens here.
If -d astr is given acts.action will have the string value 'astr'. This if just calls the do_comparison function with this value. It's the present of this (nondefault) value that triggers the function call.
This is a rather straight forward use of a parser and an argument.

How to convert string to function reference in python

I have a class that transforms some values via a user-specified function. The reference to the function is passed in the constructor and saved as an attribute. I want to be able to pickle or make copies of the class. In the __getstate__() method, I convert the dictionary entry to a string to make it safe for pickling or copying. However, in the __setstate__() method I'd like to convert back from string to function reference, so the new class can transform values.
class transformer(object):
def __init__(self, values=[1], transform_fn=np.sum):
self.values = deepcopy(values)
self.transform_fn = transform_fn
def transform(self):
return self.transform_fn(self.values)
def __getstate__(self):
obj_dict = self.__dict__.copy()
# convert function reference to string
obj_dict['transform_fn'] = str(self.transform_fn)
return obj_dict
def __setstate__(self, obj_dict):
self.__dict__.update(obj_dict)
# how to convert back from string to function reference?
The function reference that is passed can be any function, so solutions involving a dictionary with a fixed set of function references is not practical/flexible enough. I would use it like the following.
from copy import deepcopy
import numpy as np
my_transformer = transformer(values=[0,1], transform_fn=np.exp)
my_transformer.transform()
This outputs: array([ 1. , 2.71828183])
new_transformer = deepcopy(my_transformer)
new_transformer.transform()
This gives me: TypeError: 'str' object is not callable, as expected.
You could use dir to access names in a given scope, and then getattr to retrieve them.
For example, if you know the function is in numpy:
import numpy
attrs = [x for x in dir(numpy) if '__' not in x] # I like to ignore private vars
if obj_dict['transform_fn'] in attrs:
fn = getattr(numpy, obj_dict['transform_fn'])
else:
print 'uhoh'
This could be extended to look in other modules / scopes.
If you want to search in the current scope, you can do the following (extended from here):
import sys
this = sys.modules[__name__]
attrs = dir(this)
if obj_dict['transform_fn'] in attrs:
fn = getattr(this, obj_dict['transform_fn'])
else:
print 'Damn, well that sucks.'
To search submodules / imported modules you could iterate over attrs based on type (potentially recursively, though note that this is an attr of this).
I think if you are asking the same question, I came here for.
The answer is simply use eval() to evaluate the name.
>>> ref = eval('name')
This is going to return what 'name' references in the scope where the eval is
executed, then you can determine if that references is a function.

Design python like interactive shell

What is the design pattern behind python like interactive shell. I want to do this for my server but I am ending up with lot of if - then- else pattern.
For example, when I start python interpreter I get something like this
Python 2.6.7 (r267:88850, Feb 2 2012, 23:50:20)
[GCC 4.5.3] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> help
After help the prompt changes to help
Welcome to Python 2.6! This is the online help utility.
If this is your first time using Python, you should definitely check out
the tutorial on the Internet at http://docs.python.org/tutorial/.
Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules. To quit this help utility and
return to the interpreter, just type "quit".
To get a list of available modules, keywords, or topics, type "modules",
"keywords", or "topics". Each module also comes with a one-line summary
of what it does; to list the modules whose summaries contain a given word
such as "spam", type "modules spam".
help>
I think this is some king of read-eval loop design.
for a REPL, you need a context (an object which stores the REPL's state), a command parser (which parses input and produces an AST), and a way to map commands to actions (actions are generally just functions that modifies the context and/or produces side effects).
A simple REPL can be implemented like the following, where context is implemented using a simple dictionary, AST is just the inputted commands split on whitespaces, and a dictionary is used to map commands to actions:
context = {}
commands = {}
def register(func):
""" convenience function to put `func` into commands map """
# in C++, you cannot introspect the function's name so you would
# need to map the function name to function pointers manually
commands[func.__name__] = func
def parse(s):
""" given a command string `s` produce an AST """
# the simplest parser is just splitting the input string,
# but you can also produce use a more complicated grammer
# to produce a more complicated syntax tree
return s.split()
def do(cmd, commands, context):
""" evaluate the AST, producing an output and/or side effect """
# here, we simply use the first item in the list to choose which function to call
# in more complicated ASTs, the type of the root node can be used to pick actions
return commands[cmd[0]](context, cmd)
#register
def assign(ctx, args):
ctx[args[1]] = args[2]
return '%s = %s' % (args[1], args[2])
#register
def printvar(ctx, args):
print ctx[args[1]]
return None
#register
def defun(ctx, args):
body = ' '.join(args[2:])
ctx[args[1]] = compile(body, '', 'exec')
return 'def %s(): %s' % (args[1], body)
#register
def call(ctx, args):
exec ctx[args[1]] in ctx
return None
# more commands here
context['PS1'] = "> "
while True:
# READ
inp = raw_input(context["PS1"])
# EVAL
cmd = parse(inp)
out = do(cmd, commands, context)
# PRINT
if out is not None: print out
# LOOP
A sample session:
> assign d hello
d = hello
> printvar d
hello
> assign PS1 $
PS1 = $
$defun fun print d + 'world'
def fun(): print d + 'world'
$call fun
helloworld
with a little bit more trickery, you could even merge the context and commands dictionary together, allowing the shell's set of commands to be modified in the shell's language.
The name of this design pattern, if it has a name, is Read-Eval-Print Loop design pattern; so yeah, your question sorta answers itself.