Python Forum

Full Version: is it considered good practice to ...
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
is it considered good practice to return a reference to a function defined inside a function for the caller (or code it pass the reference along to) to call? would it matter for this if lambda was used?

note: this means the function that defined the function whose reference is returned, does return before that defined function gets called.

my coding intention is to eliminate a lot of tests in the function that are testing the same thing in each many calls with a choice definition that does only what is needed every time.  it does work, but i want to know how much flak i will get for doing it.
(May-08-2017, 08:48 AM)Skaperen Wrote: [ -> ]is it considered good practice to return a reference to a function defined inside a function for the caller
This is perfectly fine and one of the wonderful things about functions as first class objects.
Quote:would it matter for this if lambda was used?
There is zero difference between a function defined with lambda and a standard function aside from where it can appear syntactically.
(May-08-2017, 08:55 AM)Mekire Wrote: [ -> ]
Skaperen Wrote:would it matter for this if lambda was used?
There is zero difference between a function defined with lambda and a standard function aside from where it can appear syntactically.
i was wondering if using lambda would change how the practice is accepted by the community.  btdt both ways, so i know the interpreter accepts it.

or should i say compiler?
There is no difference and unless it is a one liner I wouldn't use the lambda.

def power(exponent):
    def _internal(n):
        return n**exponent
    return _internal


def power_lam(exponent):
    return lambda n: n**exponent


cube = power(3)
cube_lam = power_lam(3)

print(cube(4))
print(cube_lam(4))
(May-08-2017, 08:55 AM)Mekire Wrote: [ -> ]There is zero difference between a function defined with lambda and a standard function aside from where it can appear syntactically.

One other difference is that the __name__ attribute of a lambda is always '<lambda>', whereas the __name__ attribute of standard functions comes from the def statement. OTOH, I have never run into a situation where this mattered. And, of course, you can change that attribute.
You can't use annotations with lambdas, if that matters to you.

>>> def outer():
...   def inner(n: int) -> int:
...     return n ** 2
...   return inner
...
>>> x = outer()
>>> x(4)
16
>>> def outer_lamb():
...   return lambda n: int -> int: n ** 2
 File "<stdin>", line 2
   return lambda n: int -> int: n ** 2
                         ^
SyntaxError: invalid syntax
here is a snippet example i coded yesterday:

   if time_prefix:
        if sys.version_info.major < 3:
            def xprint(*args,**opts):
                opts['file']=efile
                try:
                    return print(now().strftime(etformat),*args,**opts)
                except (IOError,KeyboardInterrupt):
                    return
        else:
            def xprint(*args,**opts):
                opts['file']=efile
                try:
                    return print(now().strftime(etformat),*args,**opts)
                except (BrokenPipeError,IOError,KeyboardInterrupt):
                    return
    else:
        if sys.version_info.major < 3:
            def xprint(*args,**opts):
                opts['file']=efile
                try:
                    return print(*args,**opts)
                except (IOError,KeyboardInterrupt):
                    return
        else:
            def xprint(*args,**opts):
                opts['file']=efile
                try:
                    return print(*args,**opts)
                except (BrokenPipeError,IOError,KeyboardInterrupt):
                    return
(May-09-2017, 12:36 AM)Skaperen Wrote: [ -> ]here is a snippet example i coded yesterday:

   if time_prefix:
        if sys.version_info.major < 3:
            def xprint(*args,**opts):
                opts['file']=efile
                try:
                    return print(now().strftime(etformat),*args,**opts)
                except (IOError,KeyboardInterrupt):
                    return
        else:
            def xprint(*args,**opts):
                opts['file']=efile
                try:
                    return print(now().strftime(etformat),*args,**opts)
                except (BrokenPipeError,IOError,KeyboardInterrupt):
                    return
    else:
        if sys.version_info.major < 3:
            def xprint(*args,**opts):
                opts['file']=efile
                try:
                    return print(*args,**opts)
                except (IOError,KeyboardInterrupt):
                    return
        else:
            def xprint(*args,**opts):
                opts['file']=efile
                try:
                    return print(*args,**opts)
                except (BrokenPipeError,IOError,KeyboardInterrupt):
                    return

I think I'd write that like:
printer = print
if time_prefix:
    printer = lambda *args, **opts: print(now().strftime(etformat),*args,**opts)
errors = (IOError, KeyboardInterrupt)
if sys.version_info.major >= 3:
    errors += (BrokenPipeError, )

def xprint(*args, **opts):
    opts["file"] = efile
    try:
        return printer(*args, **opts)
    except errors:
        pass
Returning a function from inside a function is a decorator technique
nilamo: still, for the general case pattern, i will define functions.  in this case, i like what you did and will go back and see if i can put that in my code.