osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Question regarding the local function object


Nice explanation. Thank you very much.



Thanks,

Arup Rakshit
ar at zeit.io



> On 15-Mar-2019, at 6:24 PM, Calvin Spealman <cspealma at redhat.com> wrote:
> 
> This is actually part of a not entirely uncommon misconception that can arise by comparing objects only by their
> repr() outputs (the string representation created when you pass them to print).
> 
> You're comparing the ID or memory address of the objects and determining they must be the same object. In this case,
> it is a kind of illusion. The function is being garbage collected at the end of each call to sort_by_last_letter() and then, on
> the next call, that address is reused. It is just common for Python to take the next available location, and that happens to
> be the same because you're re-running generally the same code, so the same number of objects are created and destroyed
> each time.
> 
> You can see this by making a slight change: try keeping references to ALL the created functions and you'll see they all
> have different IDs so long as none of them get cleaned up. Try this slightly modified version:
> 
> functions = []
> def sort_by_last_letter(strings):
>     def last_letter(s):
>         return s[-1]
>     print(last_letter)
>     functions.append(last_letter)
>     return sorted(strings, key=last_letter)
> 
> Which produces this output:
> 
> >>> sort_by_last_letter(['ghi', 'def', 'abc'])
> <function sort_by_last_letter.<locals>.last_letter at 0x7f276dd571e0>
> ['abc', 'def', 'ghi']
> >>> sort_by_last_letter(['ghi', 'def', 'abc'])
> <function sort_by_last_letter.<locals>.last_letter at 0x7f276dd57268>
> ['abc', 'def', 'ghi']
> >>> sort_by_last_letter(['ghi', 'def', 'abc'])
> <function sort_by_last_letter.<locals>.last_letter at 0x7f276dd572f0>
> ['abc', 'def', 'ghi']
> 
> On Fri, Mar 15, 2019 at 8:47 AM Arup Rakshit <ar at zeit.io <mailto:ar at zeit.io>> wrote:
> Hi,
> 
> I am reading a book where it says that:
> 
> Just like module-level function definitions, the definition of a local function happens at run time when the def keyword is executed. Interestingly, this means that each call to sort_by_last_letter results in a new definition of the function last_letter. That is, just like any other name bound in a function body, last_letter is bound separately to a new function each time sort_by_last_letter is called. 
> 
> If that above is true, why the below program shows the same object reference for last_letter every time I call function sort_by_last_letter.
> 
> # file name is sample.py
> 
> def sort_by_last_letter(strings):
>     def last_letter(s):
>         return s[-1]
>     print(last_letter)
>     return sorted(strings, key=last_letter)
> 
> python3 -i sample.py 
> >>> sort_by_last_letter(['ghi', 'def', 'abc'])
> <function sort_by_last_letter.<locals>.last_letter at 0x1051e0730>
> ['abc', 'def', 'ghi']
> >>> sort_by_last_letter(['ghi', 'def', 'abc'])
> <function sort_by_last_letter.<locals>.last_letter at 0x1051e0730>
> ['abc', 'def', 'ghi']
> >>> sort_by_last_letter(['ghi', 'def', 'abckl'])
> <function sort_by_last_letter.<locals>.last_letter at 0x1051e0730>
> ['def', 'ghi', 'abckl']
> >>> 
> 
> 
> Thanks,
> 
> Arup Rakshit
> ar at zeit.io <mailto:ar at zeit.io>
> 
> 
> 
> -- 
> https://mail.python.org/mailman/listinfo/python-list <https://mail.python.org/mailman/listinfo/python-list>
> 
> 
> -- 
> CALVIN SPEALMAN
> SENIOR QUALITY ENGINEER
> cspealma at redhat.com <mailto:cspealma at redhat.com>  M: +1.336.210.5107 <tel:+1.336.210.5107> <https://red.ht/sig>
> TRIED. TESTED. TRUSTED. <https://redhat.com/trusted>