osdir.com


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

Ways to make a free variable local to a function?


On 3/5/2018 9:34 AM, Chris Angelico wrote:
> On Tue, Mar 6, 2018 at 12:52 AM, Terry Reedy <tjreedy at udel.edu> wrote:
>> On 3/5/2018 7:12 AM, Kirill Balunov wrote:
>>> # 1. By passing through local variable's default values
>>>
>>>       def func_local_1(numb, _int = int, _float = float, _range = range):
>>
>>
>> You are not required to mangle the names.
>>
>> def func_local_1(numb, int = int, float = float, range = range):
>> ...
>>
> 
> Even so, this does mess up the function's signature,

Which I why I only said that using the original names solves the syntax 
highlighting issue (of marking built-ins as built-ins).

> leaving your
> callers wondering if they can call it with some sort of range
> parameter. (Though in this particular instance, range() is only called
> once, so it's pretty much useless to try to optimize it.)
> 
> In theory, the CPython bytecode compiler (don't know about other
> Python implementations) could just add these as constants.  

Yes, what we really want for this sort of thing are unrebindable local 
constants.  A simple syntax change could do it.

  def func_local_1(numb; int = int, float = float, range = range):

The binding after ';' belong in the header because they should be done once.

> They'd then
> be bound at either compile time or function definition time (by
> default the former, I think, but the latter would be more useful), and
> be looked up as quickly as locals. I'm not sure how useful this would
> be, though.

I believe that the occasional practice of re-binding built-in names to 
locals can be shown to speed up loops run enough times.

> If PEP 572 [1] were to be accepted, you could do something like this:
> 
> def func(numb):
>      if ((int as int), (float as float)):
>          res = []
>          for i in range(numb):
>              res.append(int(i) + float(i))
>          return res
> 
> Syntactically a bit clunky, but keeps everything inside the function,
> and DOES create local variables. Not sure it's better than your other
> options, but it is another option.

Code in the body should be executed everytime the function is called. 
Those binding should not be as they only need to be done once.

> [1] PEP 572: https://www.python.org/dev/peps/pep-0572/

-- 
Terry Jan Reedy