Decorator In Python

What’s the Decorator in Python? Decorators are functions which modify the functionality of other functions. It’s greatly useful in Python programming.

To illustrate, see the codes

def a_decorator(func):
def wrapper():
print(‘We can do sth. before a func is called…’)
func()
print(‘… and we can do sth. after it is called…’)
return wrapper()

def a_func():
print(“Hi, I’m a_func!”)

a_func()
a_decorator(a_func)

The above codes can be written with Decorator to modify the functionality of other functions.

def a_decorator(func):
def wrapper():
print(‘We can do sth. before calling a_func…’)
func()
print(‘… and we can do sth. after it was called…’)
return wrapper

@a_decorator
def a_func():
print(“Hi, I’m a_func!”)

a_func()

More typical example with multiple decorators:

def uppercase(func):
def wrapper():
original_result = func()
modified_restult = original_result.upper()
return modified_restult
return wrapper
def strong(func):
def wrapper():
original_result = func()
modified_restult = ‘‘+original_result+’
return modified_restult
return wrapper

@uppercase
@strong
def an_output():
return ‘The quick brown fox jumps over the lazy dog.’
print(an_output())

And decorators with parameters:

def a_decorator(func):
def wrapper(*args, **kwargs):
return original_result
# …
return wrapper

def trace(func):
def wrapper(*args, **kwargs):
print(“Trace: You’ve called a function: {func.__name__}(),”,
“with args: {args}; kwargs: {kwargs}”)

orginal_result = func(*args, *kwargs)
print(“Trace: {func.__name__}{args} returned: {orginal_result}”)
return orginal_result
return wrapper

@trace
def say_hi(greeting, name=None):
return greeting + ‘! ‘ + name + ‘.’

print(say_hi(‘Hello’, ‘Jack’))

We should distinguish the other usage of decorator – @property to getter & setter, compare

class Vehicle:
def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
self.number_of_wheels = number_of_wheels
self.type_of_tank = type_of_tank
self.seating_capacity = seating_capacity
self.maximum_velocity = maximum_velocity
def number_of_wheels(self):
return self.number_of_wheels
def set_number_of_wheels(self, number):
self.number_of_wheels = number

with getter and setter

class Vehicle:
def __init__(self, number_of_wheels, type_of_tank, seating_capacity, maximum_velocity):
self.number_of_wheels = number_of_wheels
self.type_of_tank = type_of_tank
self.seating_capacity = seating_capacity
self.maximum_velocity = maximum_velocity
@property
def number_of_wheels(self):
return self.number_of_wheels
@number_of_wheels.setter
def number_of_wheels(self, number):
self.number_of_wheels = number

To get the full understanding of Getter Setter @property(decorator), discussion about scope, private/public variable, and encapsulation is needed.

The following codes should be inspected and studied thoroughly to get the sense of encapsulation. A clear positioning of variables is vital important in coding.

class Golem:
__population = 0
__life_span = 10

def __init__(self, name=None):
self.name = name
self.built_year = datetime.date.today().year
self.__active = True
Golem.__population += 1

def say_hi(self):
print(‘Hi!’)

def cease(self):
self.__active = False
Golem.__population -= 1

def is_active(self):
if datetime.date.today().year – self.built_year >= Golem.__life_span:
self.cease
return self.__active

@property
def population(self):
return Golem.__population

@population.setter
def population(self, value):
Golem.__population = value

g = Golem(‘Clay’)
g.population
g.population = 100
ga = Golem(‘New’)
g.population
ga.population
help(Golem)
Golem.__dict__
g.__dict__
hasattr(Golem, ‘population’)
getattr(Golem, ‘population’)
setattr(Golem, ‘population’, 10000)
g.population

(examples referenced from xiaolai li)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.