Browse Source

Adding example of decorator

Swaroop C H 12 years ago
parent
commit
47035101b6
1 changed files with 72 additions and 0 deletions
  1. 72 0
      17-more.md

+ 72 - 0
17-more.md

@@ -221,6 +221,78 @@ The `assert` statement should be used judiciously. Most of the time,
 it is better to catch exceptions, either handle the problem or display
 an error message to the user and then quit.
 
+## Decorators ##
+
+Decorators are a shortcut to applying wrapper functions. This is
+helpful to "wrap" functionality with the same code over and over
+again. For example, I created a `retry` decorator for myself that I
+can just apply to any function and if any exception is thrown during a
+run, it is retried again, till a maximum of 5 times and with a delay
+between each retry. This is especially useful for situations where you
+are trying to make a network call to a remote computer:
+
+~~~python
+from time import sleep
+from functools import wraps
+import logging
+logging.basicConfig()
+log = logging.getLogger("retry")
+
+
+def retry(f):
+    @wraps(f)
+    def wrapped_f(*args, **kwargs):
+        MAX_ATTEMPTS = 5
+        for attempt in range(1, MAX_ATTEMPTS + 1):
+            try:
+                return f(*args, **kwargs)
+            except:
+                log.exception("Attempt %s/%s failed : %s",
+                              attempt,
+                              MAX_ATTEMPTS,
+                              (args, kwargs))
+                sleep(10 * attempt)
+        log.critical("All %s attempts failed : %s",
+                     MAX_ATTEMPTS,
+                     (args, kwargs))
+    return wrapped_f
+
+
+counter = 0
+
+
+@retry
+def save_to_database(arg):
+    print("Write to a database or make a network call or etc.")
+    print("This will be automatically retried if exception is thrown.")
+    global counter
+    counter += 1
+    if counter < 2:
+        raise ValueError(arg)
+
+
+if __name__ == '__main__':
+    save_to_database("Some bad value")
+~~~
+
+Output:
+
+~~~
+$ python3 retry_decorator.py
+
+Write to a database or make a network call or etc.
+This will be automatically retried if exception is thrown.
+ERROR:retry:Attempt 1/5 failed : (('Some bad value',), {})
+Traceback (most recent call last):
+  File "/tmp/retry_decorator.py", line 14, in wrapped_f
+    return f(*args, **kwargs)
+  File "/tmp/retry_decorator.py", line 37, in save_to_database
+    raise ValueError(arg)
+ValueError: Some bad value
+Write to a database or make a network call or etc.
+This will be automatically retried if exception is thrown.
+~~~
+
 ## Differences between Python 2 and Python 3 ##
 
 Read these articles: