Currently I am using argparse for parsing arguments in this fashion :
outputFile = ""
input
def getArguments():
parser = argparse.ArgumentParser(description='Execute the given pig script and pipe the output to given outFile.')
parser.add_argument('-o','--outputFile', help='Output file where pig file execution output is stored.', required=True)
input = parser.parse_args()
print ("========================================")
print ("Argument to the script")
print ("outputFile = %s" % input.outputFile )
return input
input = getArguments()
outputFile = input.outputFile
print ("outputFile = %s" % outputFile )
My question is, is there a way a better AND/OR more compact way of writing parsing in this way ?
Note : I am especially trying to look for binding of parsed argument to the variable in the file. I hope to not to use "input" variable every-time I access input-argument nor do I want to have explicit variable declared just to copy the parameters from the argument-string to a variable.
As #MartijinPieters points out in the comments, there is nothing wrong with options.arg1. Firstly, I want to echo this. There isn't a very clean (or clear IMHO) way of doing what you are asking for.
What you'll need to do is convert the options object into a dictionary. This can be done using vars:
opt_dict = vars(parser.parse_args())
Then you'll have to load all the values in the dictionary into the locals. I found this question that shows examples of how to do this. I like Ken's answer for its clarity:
for item in opt_dict.iteritems():
eval('{0} = {1}'.format(*item))
But it allows for the possibility of dangerous input sneaking in. Also, this will have to be done outside of the getArguments() function.
However, I agree that the accepted answer on the previously linked question is probably the best way of doing this, which is to use the opt_dict to update globals.
NOTE: If you are doing this for a Pig python wrapper, like I suspect, then loading the the variables into the locals will actually be counter productive. The variables need to be passed into bind as a dictionary.
Related
First of all, i am somewhat new to python coding, so this might seem like a stupid question.
Problem: I am trying to create a script that allows me to import a number into (variable?operator?) names, in order to run my python script from a bash script.
Ideally i wanted to do the following (i know the syntax is wrong, but it is from my first try and captures what i would want it to do):
replica_number = 2 #2 is only for testing. It will later be exchanged with an imported number from a bash script over many different data sheets.
t_r+replica number = md.load(data_path+'potein_+replica_number+_centered.xtc', top = data_path+'potein_+replica_number+_first.gro')[1:]
What i want this to do is to automatically create the variables named t_r2 and import the files called protein_2_centered.xtc and protein_2_first.gro. However when i do this i get: SyntaxError: can't assign to operator
Does anyone know how to get around this problem, or do i just have to make a separate script for every replica?
What you need is either a list or a dictionary.
you can keep all your results in a list (without keeping the replica_number):
t_r_list = []
t_r_list.append(md.load(...)[1:]) # Run this line for each t_r you want to load
or if you want to keep the replica_number, you can use a dict:
t_r_dict = {}
t_r_dict[replica_number] = md.load(...)[1:]
You might want to read a tutorial on these data structures and how to use them, it will greatly help you on your journey with python later on and is the basis of the basis when it comes to working with data in python.
when the name of the attributes or variables is dynamic, we can use, for example, the new way Python uses for fomat Strings (f'') and then the setattr method:
The settattr method is this, is part of the builtins library:
def setattr(x, y, v): # real signature unknown; restored from __doc__
""" Sets the named attribute on the given object to the specified value."""
Here what you can do with variables
replica_number = 2
variable_name = f't_r{replica_number }'
and then check and set the aatribute:
if not hasattr(YOUR_OBJECT, variable_name ):
raise ValueError
setattr(YOUR_OBJECT, variable_name , THE_VALUE)
Use a dictionary for such kind of operations:
replica_number = md.load(...)[1:]
your_dict = {t_r : replica_number}
And access it through
your_dict[t_r]
I'm parsing system arguments in my Python project using sys.argv. At some point i had to modify the script after having written the logic that parses system args. I added a line the basically appends a string to sys.argv so the logic that parses it won't be changed -
sys.argv.append('some string here')
Is it a bad practice to modify the system arguments after they have been created for the program ?
It is bad practice to modify sys.argv in Python and it's equivalent in other languages.
In these situations I recommend a parsed_args variable which has all your parsed data from sys.argv, any default values that you would like to set, and any modifications that "middleware" would make.
In my opinion in such case it would be better to first parse those arguments using argparse.
That way you can get Namespace object, that can be modified and much easier to maintain than hardcodingsys.argv.
After that you can modify Namespace any way you want
Small example:
def parse_args():
parser = argparse.ArgumentParser(description="Description")
parser.add_argument('--file_path')
parsed_args = parser.parse_args()
return parsed_args
if __name__ == '__main__':
args = parse_args()
print(args.file_path) # the argument passed while running script
args.another_value = "value"
print(args.another_value) # value added within code
setattr(args, 'yet_another', 'value') # another way to set attributes
Generally, I like to leave the original command-line (argv) alone and work on a copy. That way, I can always see the original. Perhaps I want to compare what the user actually typed out with what I filled in later from environment variables, default values, or whatever. That's pretty handy while tracking down a problem.
Consider the case where you are using argparse. The particular library isn't important and this is a good practice for just about anything. Instead of relying on a default source, such as sys.argv, always supply it.
In this incomplete example, main() takes a list that you supply. That can be from sys.argv or whatever list you like. That's pretty handy for testing as you supply different lists to check various scenarios. This decoupling gives you quite a bit of flexibility:
def main(options):
parsed_args = process_args(options)
... rest of program ...
def process_args(options):
...do stuff to fix up options, like enable things by env vars...
parser = argparse.ArgumentParser(...)
parser.add_argument(...)
parsed_args = parser.parse_args(options) # argument instead of default
...fix up parsed_args for whatever you want to add...
return parsed_args
if __name__ == "__main__":
main(sys.argv[1:]) # remember the program name is the first item
Magic or default variables are nice for quick and dirty things, but those generally constrain you too much for larger projects where consumers might want to do things you hadn't considered. Remember, Pythonic code likes to be explicit rather than implicit (yet, so many opportunities in core to be implicit!).
I'm currently building up a library of personal debugging functions, and wanted to make a debugging print function that would provide more quality-of-life functionality than adding print(thing) lines everywhere. My current goal is to have this pseudocode function translated to Python:
def p(*args, **kwargs)
for arg in args:
print(uneval(arg), ": ", arg)
return args
The types of **kwargs and how they'd effect the output isn't as important to this question, hence why I don't use them here.
My main problem comes from trying to have some method of uneval-ing the arguments, such that I can get the string of code that actually produced them. As a use case:
>>> p(3 + 5) + 1
3 + 5: 8 # printed by p
9 # Return value of the entire expression
There's a couple of ways that I see that I can do this, and not only am I not sure if any of them work, I'm also concerned about how Pythonic any solution that actually implements these could possibly be.
Pass the argument as a string, eval it using the previous context's local identifier dictionary (how could I get that without passing it as another argument, which I definitely don't want to do?)
Figure out which line it's being run from in the .py file to extract the uneval'd strings that way (is that even possible?)
Find some metadata magic that has the information I need already in it (if it exists, which is unlikely at best).
This question already has answers here:
Calling a function from string inside the same module in Python?
(2 answers)
Python function pointer
(8 answers)
Closed 9 years ago.
Im writing a python script and what I would like to do is capture the input into a variable and then use that to call a function with that name. Here is an example:
def test():
print "You want to do a test!"
option = raw_input("What do you want to do? ") #User types in test
option()
Now this isnt working since python is not seeing option as a variable but rather is trying to call the function "option". What is the bast way to go about doing this?
eval() will work, but as #MattDMo said it can be dangerous.
A much safer way to do this, if your functions are module globals:
globals()[option]()
globals() is a dictionary mapping strings to the module global objects those strings are bound to. So globals()[option] looks up the string bound to option in that dict, and returns the object; e.g., globals["test"] returns the function object for test(). Then adding () at the end calls that function object. Bingo - you're done.
You want to be very careful about running arbitrary code, but if you absolutely need to, you can use the eval() function.
What might be a better way is to give your user a menu of options, then do testing on the contents of option to see which one they picked, then run that function.
You can use python eval.
From the help page, eval evaluates the source in the context of globals and locals. The source may be a string representing a Python expression or a code object as returned by compile().
For example:
def a():
print "Hello"
inp = raw_input()
eval(inp + "()")
On entering a at the stdin, the function a will be executed. Note that this could be dangerous without any safety checks.
This is, I suppose, an actual use for bare input:
option = input("What do you want to do? ") #User types in test
option()
This is semantically equivalent to eval(raw_input()). Note that in python 3, raw_input becomes input so you will explicitly have to eval it.
The usual caveats of this type of operation being incredibly unsafe apply. But I think that's obvious from your requirement of giving the user access to run arbitrary code, so...
I like using a dict in situations like this. You can even specify a default option if the user provides an answer that isn't expected.
def buy_it():
print "use it"
def break_it():
print "fix it"
def default():
print "technologic " * 4
menu = {"buy it": buy_it, "break it": break_it}
option = raw_input("What do you want to do? ")
menu.get(option, default)()
I have some tasks stored in db for later execution. For example i can fix task of sending email. And by cron exec task (send it). I search for best way to store code in db for later execution. For ex store it in raw string of python code and than do eval, but also i must store relative imports here..
for example for send email i must fix string like this:
s = "from django.core.mail import send_mail\n
send_mail('subj', 'body', 'email#box.ru',['email1#box.ru'], fail_silently=False)"
and later eval.. any ideas to do it best way or mb better pattern for this kind of task?
What you're doing is a bad idea mainly because you allow for way too much variability in what code will be executed. A code string can do anything, and I'm guessing there are only a few kinds of tasks you want to store for later execution.
So, figure out what the variables in those tasks are (variables in a non-programming sense: things that vary), and only store those variables, perhaps as a tuple of function arguments and a dictionary of keyword arguments to be applied to a known function.
To be even more fancy, you can have some kind of container object with a bunch of functions on it, and store the name of the function to call along with its arguments. That container could be something as simple as a module into which you import functions like Django's send_mail as in your example.
Then you can store your example call like this:
func = 'send_mail'
args = ('subj', 'body', 'email#box.ru', ['email1#box.ru'])
kwargs = {'fail_silently': False}
my_call = cPickle.dumps((func, args, kwargs))
And use it like this:
func, args, kwargs = cPickle.loads(my_call)
getattr(my_module, func)(*args, **kwargs)
Use celery for this. That's the best approach.
http://celeryproject.org/
I wouldn't use this solution at all. I would create a different handler for each task (sending a mail, deleting a file, etc). Storing code in this manner is hackish.
EDIT
An example would be creating your own format for handlers. For example each line one handler in this format:
handlername;arg1;arg2;arg3;arg4
Next you use python to read out the lines and parse them. For example this would be a stored line:
sendmail;nightcracker#nclabs.org;subject;body
Which would be parsed like this:
for line in database:
handler, *args = line.split(";")
if handler == "sendmail":
recipient, subject, body, = args[:3]
# do stuff
elif handler == "delfile":
#etc
I'd store logical commands, and exec them with something like
def run_command(cmd):
fields = map(unescape, cmd.split(";"))
handlers[fields[0]](fields[1:])
...
#handler("mail")
def mail_handler(address, template):
import whatever
...
send_mail(address, get_template(template) % user_info, ...)
this way you can have both the flexibility to add handlers without having to touching any code in the dispatcher and yet you're not writing the code details in the database that would make harder doing inspections/stats or just hot fixing jobs that didn't start yet.
To directly answer your question, eval is really only for evaluating code that will produce a result. For example:
>>> eval('1 + 1')
2
However if you simply want to execute code, possibly several lines of code, you want exec(), which by default executes inside the caller's namespace:
>>> exec("x = 5 + 5")
>>> print x
10
Note that only trusted code should be passed to either exec or eval. See also execfile to execute a file.
Having said all that, I agree with other posters that you should find a way to problematically do what you want to do instead of storing arbitrary code. You could, for example, do something like this:
def myMailCommand(...):
...
def myOtherCommand(...):
...
available_commands = {'mail': myMailCommand,
'other': myOtherCommand}
to_execute = [('mail', (arg1, arg2, arg3)),
('other', (arg1, arg2))]
for cmd, args in to_execute:
available_commands[cmd](*args)
In the above pseudo-code, I defined two methods. Then I have a dictionary mapping actions to commands. Then I go through a data structure of actions and arguments, and call the appropriate argument accordingly. You get the idea.