▲ | Demystifying decorators: They don't need to be cryptic(thepythoncodingstack.com) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
29 points by rbanffy 2 days ago | 16 comments | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | adammarples 2 days ago | parent | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
It's absolutely baffling that an article called demystifying decorators does not actually describe decorators at all, preferring to keep them a mystery. Decorators are nothing more than a special syntax for calling a function, the meat of which can easily be explained in a single paragraph including a supporting example. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | notepad0x90 2 days ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
outside of __init__, I thought it wasn't the pythonic way to directly invoke double underscore functions like closure? I recall reading that you should implement a class that overrides/implements such functions instead? I get why the author might be doing it this way to describe the topic of the post, but would calling __closure__() be acceptable in production code? | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | tccuuchffhfu a day ago | parent | prev | next [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Jdjfm df | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
▲ | sltkr 2 days ago | parent | prev [-] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
I'm not sure who this article is for, but I think it doesn't strike at the heart of the topic. Half of the article is devoted to closures, but closures aren't essential for decorators. And the __closure__ attribute is an implementation detail that is really irrelevant. (For comparison, JavaScript has closures just like Python, but it doesn't expose the closed-over variables explicitly the way Python does.) Decorators are simply higher order functions that are used to wrap functions. The syntax is a little funky, but all you need to know is that code like:
Is essentially equivalent to:
...i.e. decorators are functions that take a callable argument and return a new callable (which typically does something and then calls the argument function--or not, as the case may be).Then there are seemingly more complex expressions like:
This looks like a special kind of decorator that takes arguments, but it looks more complex than it really is. Just like `foo` was an expression referencing a function `foo(42, 'blub')` is just a regular Python function call expression. That function call should then itself return a function, which takes a function argument to wrap the function being decorated. Okay, I admit that sounds pretty complex when I write it out like that, but if you implement it, it's again pretty simple:
This is an extra level of indirection but fundamentally still the same principle as without any arguments.And yes, these examples use closures, which are very convenient when implementing decorators. But they aren't essential. It's perfectly possible to declare a decorator this way:
It's the same thing but now there are no closures whatsoever involved.The key point in all these examples is that functions in Python are first-class objects that can be referenced by value, invoked dynamically, passed as arguments to functions, and returned from functions. Once you understand that, it's pretty clear that a decorator is simply a wrapper that takes a function argument and returns a new function to replace it, usually adding some behavior around the original function. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|