Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community!

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Python Decorators

If the inner function of a closure takes a value but the outer does not, can the outer be called with an argument?

I saw this in a JavaScript function and it was hard to get my head around this. However, by calling closure a pointer to inner that helps me to make sense of this. If I understand it correctly, if the enclosed function took an argument, using your pattern in the notes, (e.g. inner(x)), you could call closure(x) even though close does not take any arguments.

I was thinking Python was so simple and yet it can do some rather complex stuff. :-)

Thanks, Bruce

Note, please see teacher notes for Python Decorators to be able to understand my question.

So cool to have a forum on a training site like this.

2 Answers

Yes it can!

Here's an example based on the one in the teacher's notes:

>>> def close():
...     def inner(x):
...         print(x)
...     return inner
>>> closure = close()
>>> closure(5)

He states in the teacher's notes that this is because closure ends up being a pointer to inner

Iain, Your code looks a bit like JavaScript. :-). Except close is not an anonymous function... but in JavaScript one might take an anonymous function and assign it to a variable, then that variable could be called as if it was a function. Based on the above, it appears that close could be called with a value, since it is a pointer to inner that does take an argument. Is it necessary to assign close() to a variable, as in the following: closure = close() for this to work? If not, then it seems like we could achieve the same goals with a call to close(5) where 5 would be supplied to inner, right? Do we gain anything by assigning close() to closure? Thanks, Bruce

No, you can't just call close(5), because close doesn't take any arguments and only returns the inner function.

If you try it, you will get an error that it expected zero arguments and instead got one.

>>> close(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: close() takes 0 positional arguments but 1 was given

If you just ran close() without assigning it to a variable, you would just get the inner function returned to you:

>>> close()
<function close.<locals>.inner at 0x02C01B70>
10,455 Points

I would like to add,

def close():
    def inner(x):
    return inner

>>> close()(5)

close can take an argument if double parens are given. Discovering some weird phenomenons in advanced Python