Skip to content

Commit 2c44bb9

Browse files
Added the Decorator code files
1 parent fad3946 commit 2c44bb9

9 files changed

Lines changed: 262 additions & 0 deletions

access_control_decorators.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Define a decorator function that takes a function as input
2+
def login_required(func):
3+
# Define a new function that wraps the original function
4+
def wrapper(*args, **kwargs):
5+
# Check if the user is logged in
6+
if user_is_logged_in():
7+
# If the user is logged in, call the original function
8+
return func(*args, **kwargs)
9+
else:
10+
# If the user is not logged in, raise an exception or redirect to login page
11+
raise Exception("User not logged in")
12+
# Return the new function
13+
return wrapper
14+
15+
# Define a function that requires login
16+
@login_required
17+
def do_something_secure():
18+
# This function can only be called if the user is logged in
19+
pass
20+
21+
def delete_account(user_id):
22+
if current_user_id() == user_id:
23+
delete_user_account(user_id)
24+
else:
25+
raise Exception("You can only delete your own account")
26+
27+
# Define a global variable to store the current user ID
28+
current_user = None
29+
30+
# Define a function to log in a user
31+
def login(user_id):
32+
global current_user
33+
current_user = user_id
34+
35+
# Define a function to log out the current user
36+
def logout():
37+
global current_user
38+
current_user = None
39+
40+
# Define a function to check if the user is logged in
41+
def user_is_logged_in():
42+
global current_user
43+
return current_user is not None
44+
45+
# Define a function to get the ID of the currently logged in user
46+
def current_user_id():
47+
global current_user
48+
return current_user
49+
50+
# Define a function to delete a user account
51+
def delete_user_account(user_id):
52+
global current_user
53+
if current_user == user_id:
54+
print(f"Deleting user account with ID {user_id}")
55+
current_user = None
56+
else:
57+
raise Exception("You can only delete your own account")
58+
59+
# Define the login_required decorator
60+
def login_required(func):
61+
def wrapper(*args, **kwargs):
62+
if user_is_logged_in():
63+
return func(*args, **kwargs)
64+
else:
65+
raise Exception("User not logged in")
66+
return wrapper
67+
68+
# Define a function that requires login
69+
@login_required
70+
def delete_account(user_id):
71+
if current_user_id() == user_id:
72+
delete_user_account(user_id)
73+
else:
74+
raise Exception("You can only delete your own account")
75+
76+
# Test the delete_account function
77+
login(1)
78+
delete_account(1) # Should print "Deleting user account with ID 1"
79+
logout()
80+
81+
try:
82+
delete_account(2) # Should raise an exception
83+
except Exception as e:
84+
print(e)
85+
86+
login(2)
87+
88+
try:
89+
delete_account(1) # Should raise an exception
90+
except Exception as e:
91+
print(e)
92+
93+
delete_account(2) # Should print "Deleting user account with ID 2"
94+
logout()
95+

class_based_decorator.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# A class-based decorator is a decorator that is implemented as a Python class. It works in the same way as a regular function-based decorator but allows for more advanced functionality by using the object-oriented features of Python.
2+
3+
# To create a class-based decorator, you define a class with a __call__() method that takes a function as its argument. This method is called whenever the decorated function is called, allowing you to modify its behavior.
4+
5+
# Here is an example of a class-based decorator that adds a prefix to the result of a function:
6+
7+
class PrefixDecorator:
8+
def __init__(self, prefix):
9+
self.prefix = prefix
10+
11+
def __call__(self, func):
12+
def wrapper(*args, **kwargs):
13+
result = func(*args, **kwargs)
14+
return self.prefix + result
15+
return wrapper
16+
17+
@PrefixDecorator('Result: ')
18+
def my_function():
19+
return 'Hello World'
20+
21+
print(my_function())

context_manager.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# A context manager is an object that defines the methods __enter__ and __exit__. The __enter__ method is called when the context manager is entered, and the __exit__ method is called when the context manager is exited. The with statement is used to enter and exit the context manager.
2+
3+
# Here's an example of how to create a context manager using the contextlib.contextmanager decorator:
4+
5+
from contextlib import contextmanager
6+
7+
@contextmanager
8+
def my_context_manager():
9+
# code to enter the context
10+
print("Entering the context")
11+
yield
12+
# code to exit the context
13+
print("Exiting the context")
14+
15+
#using the context manager
16+
with my_context_manager():
17+
print("Inside the context")

context_manager_complex_example.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import time
2+
from contextlib import contextmanager
3+
4+
@contextmanager
5+
def timer():
6+
start_time = time.time()
7+
yield
8+
end_time = time.time()
9+
elapsed_time = end_time - start_time
10+
print(f"Elapsed time: {elapsed_time:.6f} seconds")
11+
12+
13+
# example usuage
14+
with timer():
15+
time.sleep(1)

decorator_chaining.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
def bold(func):
2+
def wrapper():
3+
return "<b>" + func() + "</b>"
4+
return wrapper
5+
6+
def italic(func):
7+
def wrapper():
8+
return "<i>" + func() + "</i>"
9+
return wrapper
10+
11+
@bold
12+
@italic
13+
def hello():
14+
return "Hello, world!"
15+
16+
print(hello())

dependecy_injection.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Dependency Injection is a software design pattern that allows the application components to depend on abstractions instead of concrete implementations. The goal of Dependency Injection is to decouple the components of an application, making them more reusable, testable, and maintainable. Decorators can be used to implement Dependency Injection in Python.
2+
3+
# Here's an example of how to use a decorator to implement Dependency Injection:
4+
5+
# Define a decorator that injects a dependency
6+
def inject_dependency(dependency):
7+
def decorator(func):
8+
def wrapper(*args, **kwargs):
9+
# Inject the dependency into the function's arguments
10+
return func(dependency, *args, **kwargs)
11+
return wrapper
12+
return decorator
13+
14+
# Define a class that represents a dependency
15+
class MyDependency:
16+
def some_method(self):
17+
return "Hello, Sreekanth!"
18+
19+
# Define a class that represents a service
20+
@inject_dependency(MyDependency())
21+
class MyService:
22+
def __init__(self, dependency):
23+
self.dependency = dependency
24+
25+
def do_something(self):
26+
# Use the injected dependency
27+
result = self.dependency.some_method()
28+
print(result)
29+
30+
# Create an instance of the service and call the method
31+
service = MyService()
32+
service.do_something()

descriptors_as_decorators.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Descriptors in Python are objects that define how attribute access works for an instance of a class. Decorators, on the other hand, are functions that take another function as input and extend or modify its behavior. In Python, it is possible to use descriptors as decorators to modify the behavior of a class attribute.
2+
3+
# To use a descriptor as a decorator, we can define the descriptor object, and then apply it to a class attribute using the @ syntax. For example, let's say we have a descriptor called UpperCase, which ensures that a string attribute is always in upper case. Here's how we can use it as a decorator:
4+
5+
class PositiveNumber:
6+
def __get__(self, instance, owner):
7+
return instance._value
8+
9+
def __set__(self, instance, value):
10+
if value < 0:
11+
raise ValueError("Value must be positive")
12+
instance._value = value
13+
14+
class MyClass:
15+
def __init__(self, value):
16+
self._value = value
17+
18+
my_number = PositiveNumber()
19+
20+
my_instance = MyClass(5)
21+
print(my_instance.my_number)
22+
try:
23+
my_instance.my_number = 5 # should raise a ValueError
24+
except ValueError as e:
25+
print(e)

extend_func_using_decorators.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
def add_one(func):
2+
def wrapper(x):
3+
return func(x) + 1
4+
return wrapper
5+
6+
def subtract_one(func):
7+
def wrapper(x):
8+
return func(x) - 1
9+
return wrapper
10+
11+
@add_one
12+
def foo(x):
13+
return x * 2
14+
15+
@subtract_one
16+
def bar(x):
17+
return x * 3
18+
19+
print(foo(3)) # output: 7
20+
print(bar(4)) # output: 11

types_of_decorators.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# In Python, decorators are a way to modify the behavior of functions or classes by wrapping them with another function. Decorators can accept arguments, which allows for more flexibility in their usage.
2+
3+
# To create a decorator that accepts arguments, you first define a function that takes the arguments you want to use. This function will then return another function, which will be the actual decorator. The decorator function takes the function or class you want to modify as an argument, and returns a new version of that function or class with the modifications you specified.
4+
5+
def repeat(num):
6+
def decorator(func):
7+
def wrapper(*args, **kwargs):
8+
for i in range(num):
9+
result = func(*args, **kwargs)
10+
return result
11+
return wrapper
12+
return decorator
13+
14+
@repeat(3)
15+
def greet(name):
16+
print(f"Hello, {name}!")
17+
18+
greet("Sreekanth")
19+
20+
21+

0 commit comments

Comments
 (0)