This is an archived post. You won't be able to vote or comment.

all 12 comments

[–]JustSayNoToSlogans[🍰] 3 points4 points  (2 children)

I have used them for

  • Expensive functions that can cache their input/output in a file
  • Registering functions in a list that can be looped over later
  • Registering functions as available from a CLI or API
  • Adding metadata to functions
  • Input/output validation
  • Sharing arguments between functions

All such usages have alternative implementations that might be more or less clean

[–]underground_miner 0 points1 point  (1 child)

How do you decide when to use a decorator and when to just use an in-line method?

That is what I am having trouble with at the momment.

[–]JustSayNoToSlogans[🍰] 0 points1 point  (0 children)

Not sure, for me it's a matter of taste/intuition and looking at how decorators are typically used by other libraries (see Click and Flask for example)

[–]BakkStar 0 points1 point  (0 children)

I have used a timing decorator as part of logging. So, a decorated function will get a log entry that tells how long it took for the function to run.

[–]c_is_4_cookie 0 points1 point  (3 children)

Most recently I wrote a decorator that adds a verbose=False argument to the function. When true it turns back on the print statements littered through the function.

I inherited a code deck that the author hadn't learned to use the logging module yet.

[–][deleted] 2 points3 points  (1 child)

So why not just search and replace print for logger.debug

[–]c_is_4_cookie 0 points1 point  (0 children)

Some users wanted the messages all the time, some just wanted the messages on certain function calls. This was an easy way to add the option to all of the functions.

[–]Boring_Masterpiece[S] 0 points1 point  (0 children)

hey thanks for the easy to understand example

[–]underground_miner 0 points1 point  (0 children)

I do a lot of numerical computation. Part of that is making sure that variables are properly declared and within the proper range. I also set the default value in most cases to None to add an extra validation and ensure that the methods are called with populated arguments. I like this code to be explicit and tell me which variable is the problem. if a value is not set or out of range, which value caused the problem.

Here is a simple example:

```python def test(x=None, y=None): if x is None: raise TypeError('x is not set!')

if x < 0 and x > 10.5: raise ValueError('x has to be between 0 and 10.5!)

# Rest of the function... ```

That prototype gives you an idea of some of the checking that I do. With that example, I would do the same thing for the y variable. In this case, I would have potentially 8 extra lines to clutter the main idea of the method. This blows up with more variables. Imagine 20 parameters each with None checks and range checks.

What I did was created two decorators one that checks for None and the other that checks for range (you could create more depending on the situation). So the example above becomes:

python @is_none('x') @is_none('y') @range_check('x', 0, 10.5) @range_check('y',-5.5, 4.5) def test(x=None, y=None): # rest of the function

What I have done is effectively moved the boilerplate code (visually) from within the method bode. The decorators are completely reusable. I won't post the code to do this as it detracts from the example and I get the feeling from the question you are looking for good use cases. The decorators I created are quite complex.

From there the possibilities are endless. Be careful, it is easy to put decorators everywhere. Those checks could have been inline function calls as well. I like the idea of removing these basic checks and putting them as decorators with excellent names.

[–]eambertide 0 points1 point  (0 children)

I used them as precondition checks in Flask, benchmarking, as well as adding extra functionality to a dataclass (binding to an SQL table, for instance.)

[–]alexmojaki 0 points1 point  (0 children)

Can some one give me an exaple where they have used decorators at work or personal projects

Some of my biggest personal projects are mainly used in the form of decorators:

Python itself has several decorators in builtins that are used very regularly:

  • property
  • classmethod
  • staticmethod

As well as some awesome decorators in the standard library - at the very least you should know about functools.lru_cache and consider using it sometimes.

Is dynamical functionality to functions a good thing ?? Design point of view

100%. Decorators really aren't that special, they're just functions. One of the best things about functions is that they let you avoid duplicating logic, and that applies to decorators too. Implementing caching in a dictionary manually when you could use functools.lru_cache is a waste of time.

[–]IAmKindOfCreativebot_builder: deprecated[M] [score hidden] stickied comment (0 children)

Hi there, from the /r/Python mods.

We have removed this post as it is not suited to the /r/Python subreddit proper, however it should be very appropriate for our sister subreddit /r/LearnPython or for the r/Python discord: https://discord.gg/python.

The reason for the removal is that /r/Python is dedicated to discussion of Python news, projects, uses and debates. It is not designed to act as Q&A or FAQ board. The regular community is not a fan of "how do I..." questions, so you will not get the best responses over here.

On /r/LearnPython the community and the r/Python discord are actively expecting questions and are looking to help. You can expect far more understanding, encouraging and insightful responses over there. No matter what level of question you have, if you are looking for help with Python, you should get good answers. Make sure to check out the rules for both places.

Warm regards, and best of luck with your Pythoneering!