added decorator explaination

This commit is contained in:
PeaceNira 2024-11-08 20:13:54 +00:00
parent df0921240c
commit 67f2ce93e6
2 changed files with 40 additions and 0 deletions

40
4_decorators.py Normal file
View file

@ -0,0 +1,40 @@
"""
Now that we have covered the basics of a function and variables, we will quickly cover decorators.
Decorators are extremely useful and are used to wrap existing functions in another function, you can use this
for many different things, a good example is permission checks.
Key Concepts:
**wrappers** are used to nest functions in another generalized function, this can be used for various things e.g (logging info)
**args** we use the "*args* paramater to capture all positional based arguements, these come before keyword arguements.
it sounds more complicated than it is, e.g
myfunction(arg1, arg2, arg3)
**kwargs** are arguements defined by a key rather than their position. e.g
myfunction(keyword1="foo", keyword2="bar")
**__name__** is just another magic/dunder method that returns the function's name.
"""
import time
def timed(function: any) -> any: #initial function takes in another function as a arguement
def wrapper(*args: any, **kwargs: any) -> any: # the wrapper, takes in the arguements and keyword arguements from the function
before = time.time()
output = function(*args, **kwargs)
after = time.time()
print(f"{function.__name__} with output of {output} took {after-before}s to execute.")
return output # ensure the output of the function is passed back
return wrapper
@timed
def exponential_function(n: int) -> int: # O(n^2) time complexity due to nested loops
output = 0
for i in range(n):
for j in range(i):
output += j
return output
# Test the decorated function
print(exponential_function(1000)) # This will take some time to compute
exponential_function(10000) # This will take noticeably more time to compute

0
5_pandas.py Normal file
View file