1

I am trying to understand the background of why the following works:

def part_string(items):
    if len(items) == 1:
        item = items[0]
        def g(obj):
            return obj[item]
    else:
        def g(obj):
            return tuple(obj[item] for item in items)
    return g

my_indexes = (2,1)
my_string = 'ABCDEFG'
function_instance = part_string(my_indexes)
print(function_instance(my_string))
# also works: print(part_string(my_indexes)(my_string))

how come I can pass my_string to function_instance object even though I already passed my_indexes attributes to part_string() when creating function_instance? why Python accepts my_string implicitly?

I guess it has something to do with the following, so more questions here: what is obj in g(obj)? can this be something other e.g. g(stuff) (like with self which is just a convention)? what if I want to pass 2 objects to function_instance? how do I refer to them in g(obj)?

Can You recommend some reading on this?

simplynail
  • 313
  • 1
  • 4
  • 13
  • 1
    See [Can you explain closures (as they relate to Python)?](http://stackoverflow.com/questions/13857/can-you-explain-closures-as-they-relate-to-python) – PM 2Ring Mar 24 '16 at 16:41

1 Answers1

0

What you're encountering is a closure.

When you write part_string(my_indexes) you're creating a new function, and upon calling it, you use the old variables you gave to part_string together with the new variables given to function_instance.

You may name the inner function whatever you want, and there is no convention. (obj is used in here but it can be pie. There are no conventions for this except func for function closures (decorators).

If you wish to pass two variables to the function, you may define two variables to the g(obj) function:

def g(var1, var2):
    ...

Here's some more info regarding closures in python.

Bharel
  • 23,672
  • 5
  • 40
  • 80