Deep vs. shallow copy?
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Thu Mar 13 21:41:58 EDT 2014
On Fri, 14 Mar 2014 10:55:44 +1100, Chris Angelico wrote:
> On Fri, Mar 14, 2014 at 10:41 AM, Steven D'Aprano
> <steve+comp.lang.python at pearwood.info> wrote:
>> Are you trolling again?
>>
>> I'm sure that you know quite well that Python doesn't have a procedure
>> type. It uses a single keyword, def, for creating both functions and
>> functions-that-return-None.
>
> I'm going to troll for a moment and give you a function that has no
> return value.
Heh, you're not trolling. You're just trying to be pedantic. But not
pedantic enough...
> def procedure():
> raise Exception
This does have a return result, and it is None. It's just that the
function never reaches the return, it exits early via an exception.
py> from dis import dis
py> dis(procedure)
2 0 LOAD_GLOBAL 0 (Exception)
3 RAISE_VARARGS 1
6 LOAD_CONST 0 (None)
9 RETURN_VALUE
That *may* be able to be optimized away by a smarter compiler, or perhaps
it can't be. There may be some technical reason why code objects have to
end with a return no matter what:
py> dis(compile("func()", "", "exec"))
1 0 LOAD_NAME 0 (func)
3 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
6 POP_TOP
7 LOAD_CONST 0 (None)
10 RETURN_VALUE
Or maybe it's just an optimization that nobody has bothered with since
the benefit is so trivial. But either way, all callables (sub-routines)
in Python are functions, i.e. in principle they could, or should, return
a result, even if in practice some of them don't. There is no callable
type which lacks the ability to return a result.
Naturally they may not actually return a result if they never exit:
def this_is_a_function():
while 1:
pass
return "You'll never see this!"
or if they exit via an exception:
def also_a_function():
if 1:
raise ValueError
return "You'll never see this either!"
or if they just kill the running Python environment stone dead:
def still_a_function():
import os
os._exit(1)
return "Have I beaten this dead horse enough?"
> But seriously, this is something that some functions do when they need
> to distinguish between returning something and not returning anything.
> Look at a dictionary's subscripting (which is effectively a function
> call):
>
>>>> x={1:2}
>>>> x[1]
> 2
>>>> x[3]
> Traceback (most recent call last):
> File "<pyshell#17>", line 1, in <module>
> x[3]
> KeyError: 3
Yes, I'm aware that Python functions can raise exceptions :-)
> It can't return None to indicate "there was no such key in the
> dictionary", so it raises instead. There's only one way for a Python
> function to not have a return value: it has to not return.
Exactly my point. Functions return a value, and None is a value;
procedures return, but not with a value. Python has the former, but not
the later. Instead, we make do with the convention that something which
is *intended* to be used as a procedure should return None to signal
that, and the caller should just ignore the return result.
--
Steven D'Aprano
http://import-that.dreamwidth.org/
More information about the Python-list
mailing list