I have a python function that returns
def edit_user(request):
error = False
errMsg = ""
id = int(request.POST.get("add_user"))
if config.editUser(id) != True
error = True
errMsg = _('Failed to edit existing user.')
return [error, errMsg]
I'm calling this function from another python function.
How do I get these two return values, (error and errMsg) into two separate variables?
Like this: error, errMsg = edit_user(request).
Just assign the results to a list or tuple:
error,errMsg = edit_user(...)
(error,errMsg) = edit_user(...)
[error,errMsg] = edit_user(...)
The first syntax is the most preferable.
Hui Zheng is right - error, errMsg = edit_user(request) will do it.
The process is called unpacking and can be used to unpack complicated data structures (see this SO question for another example, and have a look at the python docs for more info).
Just to add to other answers: there's no reason to make a list here at all. Just do this:
return error, errMsg
Related
I have a function I'm using to test in an if/then.
The issue is that I'm executing the function BOTH in the if conditional, and then again after the if statement because the function returns two items.
This just seems wasteful and I'm trying to think of ways to improve this. Here's a really basic version of what I'm trying to avoid: "True" is returned to allow the condition to pass, but then then "coolstuff()" is executed again to get more information from the function.
"coolstuff()" could possibly return false, so I can't use the returned string "stuff" as the test.
def coolstuff():
return True, "stuff"
if coolstuff()[0]:
coolthing = coolstuff()[1]
print coolthing
There's gotta be a better way to do this, no? My brain is melting a little as I try to hash it out.
I basically want to do something like this (invalid) syntax:
def coolstuff():
return True, "stuff"
if a, b == coolstuff() and a:
print b
Just collect both results into variables
a, b = fn()
if a:
# work with b
def coolstuff():
if valid:
return "stuff"
return None
data = coolstuff()
if data:
print(data)
Call the function and capture the entire returned value:
x = coolstuff()
Now you have access to both parts of the returned value, in x[0] and x[1].
Store it:
state, coolvar = coolstuff()
if state:
do_whatever(coolvar)
If in newer Python, you could use the dreaded walrus (but I prefer ti7's approach of just assigning in a separate line):
if (x := coolstuff())[0]:
print(x[1])
I came up with this situation while writing code in python for my project and began to think on this problem.
The problem is given a string containing a function name with its arguments how do we get the arguments and the function name given the number of arguments in the function.
My first thought was:
s = 'func(a,b)'
index = s.find('(')
if(index != -1):
arg_list = s[index+1:-1].split(',')
func_name = s[:index]
But as I began to think more I realised what if function is specified within functions which has its own arguments?
func1(func2(a,b,c),func3(d,e))
With my above approach I will end up with right function name but arg_list will contain
["func2(a","b","c)","func3(","d","e)"]
How to generically solve this situation?
If your language looks sufficiently like Python, use ast.parse():
import ast
def parse(s):
tree = ast.parse(s)
print ast.dump(tree)
parse('f(a,b)')
All the information you need will be encoded in tree.
>>> import pyparsing as pyp
>>> def get_name_and_args(a_string):
index = a_string.find('(')
if index == -1:
raise Exception("No '(' found")
else:
root_function, a_string = a_string[:index], a_string[index:]
data = {}
data[root_function] = pyp.nestedExpr().parseString(a_string).asList()[0][0].split(',')
return data
>>> print get_name_and_args("func(a,b)")
{'func': ['a', 'b']}
This solves the simpler example you gave using the pyparsing module. I wasn't sure exactly how you wanted the output formatted, and it doesn't work for the nested example. However this should be enough to get you started
I have the following code in python:
def update(request, id):
success = 0
try:
product = Mattress.objects.get(id=id)
success = 1
except Mattress.DoesNotExist:
pass
if success == 1:
return render_to_response("success.html")
else:
return render_to_response('failure.html')
Is this code a valid way to check the "success" boolean. If the code passes through the try statement, will "success" be changed to 1 or is it remaining at 0?
Answering your question:
Are booleans mutable in python?
Yes and no. Variables that are assigned a boolean value are (probably always, and definitely in this case) mutable, yes. They're also not restricted to being assigned boolean values, as variables are not staticly typed.
But the booleans True and False themselves are not mutable. They are singletons that cannot be modified.
Looking at your actual code:
if success = 1:
Is not valid syntax, you want a == there. Also, idiomatically speaking you should not use 0 and 1 for success and failure values you should use True and False. So you should refactor to something like this:
def update(request):
success = False
try:
product = Mattress.objects.get(id=id)
success = True
except Mattress.DoesNotExist:
pass
if success:
return render_to_response("success.html")
else:
return render_to_response('failure.html')
Yes. success will be changed to 1 on success.
There are a few things wrong with this snippet.
Firstly, you're not using a boolean type. Python's booleans are True and False.
Second, you're not comparing in your if statement. That line isn't valid in Python 3. What you're looking for is: if success == 1: or if success == True:
You would still be able to assign a boolean value to a variable regardless of boolean immutability. I believe they are stored as a primitive type, so they're as immutable as any other primitive type.
You should consider using an actual boolean and not an integer. You can set success to true or false and Python will interpret them as keywords to the values of 1 and 0. Using numbers can be a bit tricky as some languages interpret things different. In some languages 0 is false but any value besides 0 is considered true. However the answer to your question is yes, it will work just fine.
Probably the question you are asking is not even related with the problem you are trying to solve. I think there is a a Pythonic way to achieve what you want by:
def update(request):
try:
product = Mattress.objects.get(id=id)
except Mattress.DoesNotExist:
template_name = 'failure.html'
else:
template_name = 'success.html'
return render_to_response(template_name)
Basically if the exception is thrown, i.e., the template you will render will be 'failure.html'. On the other hand, if the query is performed successfully, 'success.html' will be rendered.
I am still new to Python and have been reviewing the following code not written by me.
Could someone please explain how the first instance of the variable "clean" is able to be be called in the check_arguments function? It seems to me as though it is calling an as yet undefined variable. The code works but shouldn't that call to "clean" produce an error?
To be clear the bit I am referring to is this.
def check_arguments(ages):
clean, ages_list = parse_ages_argument(ages)
The full code is as follows...
def check_arguments(ages):
clean, ages_list = parse_ages_argument(ages)
if clean != True:
print('invalid ages: %s') % ages
return ages_list
def parse_ages_argument(ages):
clean = True
ages_list = []
ages_string_list = ages.split(',')
for age_string in ages_string_list:
if age_string.isdigit() != True:
clean = False
break
for age_string in ages_string_list:
try:
ages_list.append(int(age_string))
except ValueError:
clean = False
break
ages_list.sort(reverse=True)
return clean, ages_list
ages_list = check_arguments('1,2,3')
print(ages_list)
Python doesn't have a comma operator. What you are seeing is sequence unpacking.
>>> a, b = 1, 2
>>> print a, b
1 2
how the first instance of the variable "clean" is able to be be called in the check_arguments function?
This is a nonsensical thing to ask in the first place, since variables aren't called; functions are. Further, "instance" normally means "a value that is of some class type", not "occurrence of the thing in question in the code listing".
That said: the line of code in question does not use an undefined variable clean. It defines the variable clean (and ages_list at the same time). parse_ages_argument returns two values (as you can see by examining its return statement). The two returned values are assigned to the two variables, respectively.
I have a class Flight, and I'm trying initialize it, but I have a syntax error in
print x=Flight(flightFromInput='nebrasca')
This is a content of my example file
class Flight:
flightFrom = None
flightTo = None
departureDate = None
arrivalDate=None
airline=None
serviceClass=None
departureAirport = None
arrivalAirport=None
#----------------------------------------------------------------------
def __init__(self,flightFromInput):
self.flightFrom = flightFromInput
print x=Flight(flightFromInput='nebrasca')
What is wrong with this code?
You should write
x = Flight(flightFromInput='nebrasca')
print x
In python an assignment statement doesn't return the assigned value. So you cannot use it within another statement. As the other answers suggested, you can work around this by printing x in a separate line.
Note, that there are exceptions though:
a = b = 0 # works
a = (b = 0) # does not work
The first case is a special case allowed for convenience when you want to assign the same value to multiple variables. In the second case you clearly tell the compiler that b=0 is a separate statement, but as it doesn't return a value the outer assignment to a leads to the resulting SyntaxError.
Hope this explains it a bit more clearly, why you should do print x after assigning it.
Contrary to C, in Python assignments are statements only and not expressions. Therefore they do not have their own value. Try this:
x = Flight(flightFromInput='nebrasca')
print x