Reputation: 15
I am trying to implement a simple logging feature within my app.
class messages(object):
# Implement decorator here
def on(self):
def wrapper():
# Do something here
return wrapper
def off(self):
def wrapper():
# Do something here
return wrapper
class website(object):
@messages.on #This line can be switched on/off
def login(self):
# Do a whole bunch of stuff here
self.response = "[+] Login Succeeded!"
website = website()
website.login() # prints self.response based on @messages.on/off
But i am not sure what i need to apply in my decorator. I have tried creating instances and adding params but mostly receive TypeError. I am fairly new to decorators. Any help would be appreciated and i'd love to remember this for next time.
Upvotes: 1
Views: 363
Reputation: 48067
Below is the sample decorator that you may use:
class Utilities:
@staticmethod
def add_logger(func):
def wrapped_func(*args, **kwargs):
# Sample logic, feel free to update this
try:
func_response = func(*args, **kwargs)
except:
print 'I am error handled by logger'
func_response = None
return func_response
return wrapped_func
Let's define your class now:
class Dog(object):
@Utilities.add_logger
def bark(self):
print 'In bark'
@Utilities.add_logger
def my_error_function(self):
print 'In my_error_function'
raise Exception # <--- Raises Exception
Now, let's check how it works:
>>> dog = Dog()
>>> dog.bark()
In bark
>>> dog.my_error_function()
In my_error_function
I am error handled by logger # Content from logger in case of exception
Note: You shouldn't really be creating a class
here to store utility function. Create a separate utility file and write such functions over there.
Without class, your decorator should be like (let's say in utility.py):
def add_logger(func):
def wrapped_func(*args, **kwargs):
# Sample logic, feel free to update this
try:
func_response = func(*args, **kwargs)
except:
print 'I am error handled by logger'
func_response = None
return func_response
return wrapped_func
For using it, simply do:
import utility
class Dog(object):
@utility.add_logger
def bark(self):
print 'In bark'
Upvotes: 0
Reputation: 564
If you just want Dog to bark (like in the example), there is no need for enabling a decorator
class Dog(object):
def __init__(self):
self.sound = "Woof!"
def bark(self):
return self.sound
If you want to enable logging for some functions in class, here is a code that does that with explanation in comments
from functools import wraps
class Utilities(object):
@staticmethod # no default first argument in logger function
def logger(f): # accepts a function
@wraps(f) # good practice https://docs.python.org/2/library/functools.html#functools.wraps
def wrapper(self, *args, **kwargs): # explicit self, which means this decorator better be used inside classes only
print("Before:", self.sound)
result = f(self, *args, **kwargs)
print("After:", self.sound)
return result
return wrapper
class Dog(object):
def __init__(self):
self.sound = "Woof!"
@Utilities.logger
def run(self):
"""Perform running movement"""
print("Running")
Example:
>>> dog = Dog()
>>> dog.run()
Before: Woof!
Running
After: Woof!
Though after all there is no need to store decorators functionality in the Utilities
class - it is better to have a separate module (file) named utils
and put decorator there as a standalone function
Upvotes: 2