473,324 Members | 2,531 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,324 software developers and data experts.

Python function returns:

I am still new to Python but have used it for the last 2+ months.
One thing I'm still not used to is that functions parameters can't
change as expected. For example in C, I can have
status = get_network_info (strIpAddress, &strHostname, &nPortNumber)
where this fictitious function returns a status, but also returns modified
values for a hostname and a port number.
In Python, there does not seem to be an easy way to have functions return
multiple values except it can return a list such as:
strHostname, nPortNumber, status = get_network_info (strIpAddress,
strHostname,
nPortNumber)
Am I missing something obvious? Is there a better, or more standard way
to return values from functions?

Thanks in advance:
Michael Yanowitz
May 4 '06 #1
4 2730
Michael Yanowitz wrote:
I am still new to Python but have used it for the last 2+ months.
One thing I'm still not used to is that functions parameters can't
change as expected. For example in C, I can have
status = get_network_info (strIpAddress, &strHostname, &nPortNumber)
where this fictitious function returns a status, but also returns
modified
values for a hostname and a port number.
In Python, there does not seem to be an easy way to have functions
return
multiple values except it can return a list such as:
strHostname, nPortNumber, status = get_network_info (strIpAddress,
strHostname,
nPortNumber)
Am I missing something obvious? Is there a better, or more standard way
to return values from functions?


No, that exactly is the way to go. But usually one uses tuples and the
possibility of sequence-unpacking together to reach a solution tha at least
to my eye looks more favorable:
def foo(a, b):
return a*b, a+c

a = 10
b = 20

a, b = foo(a, b)
Diez
May 4 '06 #2
Michael Yanowitz wrote:
In Python, there does not seem to be an easy way to have functions
return
multiple values except it can return a list such as:
strHostname, nPortNumber, status = get_network_info (strIpAddress,
strHostname,
nPortNumber)
Am I missing something obvious? Is there a better, or more standard
way
to return values from functions?


The only obvious thing you are missing is that you don't pass in values
which are only results. Duplicating the parameters and results as you have
above would be unlikely to happen very much in practice.

Oh, and it doesn't return a list, it actually returns a tuple but it is
easiest just to think of your function as just returning three results.

Returning additional results is better than rebinding parameters because it
makes it really clear at the point of calling which variables are
parameters and which are results.

The other not very pythonic thing about your example is that it returns a
status code: Python largely tends towards using exceptions rather than
status codes, so if in C you had:

switch ((status=get_network_info(addr, &host, &port)) {
case S_OK:
break;
case ERROR_1:
... handle error ...
break;
case default:
... handle other errors ...
};

In Python you would have something like:

try:
host, port = get_network_info(addr)
except ERROR_1:
... handle error ...
except:
... handle other errors ...

which means you can handle the error either right next to the call or at
some outer level (you don't have to manually propogate your status), you
can't accidentally forget to check the status code, and the actual call is
much simpler and clearer (especially if the error is handled at some outer
level).
May 4 '06 #3
Michael Yanowitz wrote:
I am still new to Python but have used it for the last 2+ months.
One thing I'm still not used to is that functions parameters can't
change as expected.

For example in C, I can have
status = get_network_info (strIpAddress, &strHostname, &nPortNumber)
You have to understand that Python and C are totally different beasts.

A C variable is mostly symbolic name for a memory address, tagged with
type infos. Assigning to a variable means storing a value at this
address. Reading a variable means retrieving whatever value is stored at
this memory address.

Python does not in fact have a concept of "variables". It has names and
objects. A binding is the association (in a hash table) of a symbolic
name (which is nothing more than a name) and a reference (read:
something like a smart pointer) to an object (which is itself a complex
data structure). So-called "assignement" (correct term is "binding")
'binds' together a name and a reference to an object. Except for some
special cases (mainly objects - which are they're own namespaces - and
when using the 'global' statement), this creates an entry in the current
namespace. Also, rebinding a name has no effect on other names bound to
the same object.

Function's params are bindings in the function's local namespace. This
means that the params *names* are local to the function. So rebinding a
param in a function won't have no effect on bindings in the caller's
namespace.

*But* - since many names can refer to the same object - *modifying* the
object referenced by a name will, well, modify this object, so this
modification will be visible everywhere.

ie (dummy example):

def appendToList(alist, what):
alist.append(what)

mylist = []
appendToList(mylist, 42)
print mylist

What doesn't work as you'd expect is:

def failsToHaveSideEffects(alist, anything):
print "before rebinding : alist = ", alist, " - anything = ", anything
alist = anything
print "after rebinding: alist = ", alist

mylist = []
print "before function call, mylist = ", mylist
failsToHaveSideEffects(mylist, 42)
print "after function call, mylist = ", mylist
So as you can see, it's quite possible for a function to *modify* it's
params - it's just rebindings of params that won't have side effects
outside the function's namespace.

Now, there is the case of immutable types (int, strings, tuples, ....).
As implied, one cannot modify objects of these types - just create them.
So in order to have a function that "change the value" of an immutable
object, you have to wrap it into a mutable object, ie:

def getAnswer(alist):
alist[0] = "42"

answer = ["answer is ?"]
getAnswer(answer)
print "answer is : ", answer[0]

(snip)
In Python, there does not seem to be an easy way to have functions return
multiple values except it can return a list such as:
strHostname, nPortNumber, status = get_network_info (strIpAddress,
strHostname,
nPortNumber)
Am I missing something obvious? Is there a better, or more standard way
to return values from functions?


This *is* the 'standard' (ie: idiomatic) way to return multiple values
from a function. The C idiom of passing pointers to variables that are
to be modified comes from C's limitations, namely no exception handling
and only one return value[1], which leads to using the return value as a
status report and relying on side effect for useful values.

[1] To be pedantic, Python only allows one return value too - but this
value can be a tuple or list, and then one can take advantage of
tuple/list expansions that allows multiple assignment...

HTH
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
May 4 '06 #4
Michael Yanowitz <m.********@kearfott.com> wrote:
In Python, there does not seem to be an easy way to have functions return
multiple values except it can return a list such as:
strHostname, nPortNumber, status = get_network_info (strIpAddress,
strHostname,
nPortNumber)
Am I missing something obvious? Is there a better, or more standard way
to return values from functions?


I'm kind of repeating what other people have said, but there
isn't a better way. Not just in Python, but in any language.
If your function is returning multiple values, why should you
have to split them into one privileged "return value" plus a
bunch of Out (or InOut) parameters? That's a historical mis-
feature of older languages, and one which more newer languages
would do well to fix.

--
\S -- si***@chiark.greenend.org.uk -- http://www.chaos.org.uk/~sion/
___ | "Frankly I have no feelings towards penguins one way or the other"
\X/ | -- Arthur C. Clarke
her nu becomeţ se bera eadward ofdun hlćddre heafdes bćce bump bump bump
May 4 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

63
by: Davor | last post by:
Is it possible to write purely procedural code in Python, or the OO constructs in both language and supporting libraries have got so embedded that it's impossible to avoid them? Also, is anyone...
32
by: David | last post by:
Hi I'm trying to teach myself python and so far to good, but I'm having a bit of trouble getting a function to work the way I think it should work. Right now I'm taking a simple program I wrote in...
1
by: David | last post by:
I have this error message poping up when I try to import a module I made in C using the Python/C API. Everything compiles like a charm. Gives me this error message : Traceback (most recent...
20
by: Xah Lee | last post by:
Sort a List Xah Lee, 200510 In this page, we show how to sort a list in Python & Perl and also discuss some math of sort. To sort a list in Python, use the “sort” method. For example: ...
14
by: Java and Swing | last post by:
static PyObject *wrap_doStuff(PyObject *self, PyObject *args) { // this will store the result in a Python object PyObject *finalResult; // get arguments from Python char *result = 0; char *in=...
0
by: Xah Lee | last post by:
One-Liner Loop in Functional Style Xah Lee, 200510 Today we show a example of a loop done as a one-liner of Functional Programing style. Suppose you have a list of file full paths of...
15
by: Claudio Grondi | last post by:
Let's consider a test source code given at the very end of this posting. The question is if Python allows somehow access to the bytes of the representation of a long integer or integer in...
0
by: Kurt B. Kaiser | last post by:
Patch / Bug Summary ___________________ Patches : 385 open (+21) / 3790 closed (+21) / 4175 total (+42) Bugs : 1029 open (+43) / 6744 closed (+43) / 7773 total (+86) RFE : 262 open...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.