On Sat, 9 May 2015 03:49 am, Chris Angelico wrote:

> On Sat, May 9, 2015 at 3:36 AM, Steven D'Aprano
> <steve+comp.lang.pyt...@pearwood.info> wrote:
>> On Sat, 9 May 2015 02:02 am, Chris Angelico wrote:
>>> Aside from constructing two closures in the same context and proving
>>> that their __code__ attributes point to the same object, is there any
>>> way to distinguish between "code object compilation time" and "def
>>> execution time"? I just played around with it, and as far as I can
>>> tell, code objects are completely read-only.
>>
>> Sure there is. Write this Python code:
>>
>> py> source = """\
>> ... print "Function definition time."
>> ... def func():
>> ...     pass
>> ... """
>> py> print "Compile time."; code = compile(source, '', 'exec')
>> Compile time.
>> py> exec(code)
>> Function definition time.
> 
> Yes, but can you *distinguish* them in terms of default argument
> versus code object creation? How do you know that the function's code
> object was created when compile() happened, rather than being created
> when the function was defined? Is there anything that lets you in any
> way show different behaviour based on that timing difference?

I think the answer is, "yes, but it's only by peering into the
implementation".

You can read the source code of the Python compiler.

You can compile the code, and then disassemble the byte-code to see that the
code object exists but the function is assembled when the byte-code runs:


py> from dis import dis
py> code = compile("def spam(x): return x + name", "", "exec")
py> dis(code)
  1           0 LOAD_CONST               0 (<code object spam at 0xb7b88160,
file "", line 1>)
              3 LOAD_CONST               1 ('spam')
              6 MAKE_FUNCTION            0
              9 STORE_NAME               0 (spam)
             12 LOAD_CONST               2 (None)
             15 RETURN_VALUE



Contrast that to what happens with a default argument:


py> code = compile("def spam(x=name+1): return x + name", "", "exec")
py> dis(code)
  1           0 LOAD_NAME                0 (name)
              3 LOAD_CONST               0 (1)
              6 BINARY_ADD
              7 LOAD_CONST               1 (<code object spam at 0xb7bce890,
file "", line 1>)
             10 LOAD_CONST               2 ('spam')
             13 MAKE_FUNCTION            1
             16 STORE_NAME               1 (spam)
             19 LOAD_CONST               3 (None)
             22 RETURN_VALUE




-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to