Deep vs. shallow copy?

Chris Angelico rosuav at gmail.com
Fri Mar 14 01:22:43 CET 2014


On Fri, Mar 14, 2014 at 11:08 AM, Ian Kelly <ian.g.kelly at gmail.com> wrote:
> On Thu, Mar 13, 2014 at 5:55 PM, Chris Angelico <rosuav at gmail.com> wrote:
>> I'm going to troll for a moment and give you a function that has no
>> return value.
>>
>> def procedure():
>>     raise Exception
>
>>>> import dis
>>>> dis.dis(procedure)
>   2           0 LOAD_GLOBAL              0 (Exception)
>               3 RAISE_VARARGS            1
>               6 LOAD_CONST               0 (None)
>               9 RETURN_VALUE

That's a return value in the same way that exec() has a return value
[1]. If somehow the raise fails, it'll return None.

>>>> def get_procedure_return_value():
> ...     """Returns the return value of procedure()."""
> ...     return procedure.__code__.co_consts[0]
> ...
>>>> print(get_procedure_return_value())
> None
>
> Look, there it is!

Succeeds by coincidence. From what I can see, *every* CPython function
has const slot 0 dedicated to None. At least, I haven't been able to
do otherwise.

>>> def function(x):
    return x*2+1

>>> import dis
>>> dis.dis(function)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (2)
              6 BINARY_MULTIPLY
              7 LOAD_CONST               2 (1)
             10 BINARY_ADD
             11 RETURN_VALUE
>>> function.__code__.co_consts
(None, 2, 1)

Your return value retriever would say it returns None still, but it doesn't.

Trollbridge: you have to pay a troll to cross.

ChrisA

[1] I'm not talking about Python's 'exec' statement, but about the
Unix exec() API, eg execlpe() - see http://linux.die.net/man/3/exec



More information about the Python-list mailing list