Reputation: 113
I am new to python and cant understand the decorators concept. I am trying to implement two decorators, one, nonNegative which assumes an arbitrarily long list of integer arguments and throws an Exception if any is less than 0, and another, allCaps, which assumes an arbitrarily long list of string arguments, and capitalizes them. Then, write a simple function to test each, wrap it, and demonstrate that each decorator works.
I have started and have come to this point.
#!/usr/local/bin/python2.7
def NonNegative(inputs):
for i in inputs:
if i<0:
raise exception
def allCaps(inputs2):
for i in inputs2:
a = i.upper()
print a
def inputs
def inputs2():
inputfile = open ("input.txt")
sentence = inputfile.readlines()
words = (sentence[0].split())
return words
NonNegative(inputs)
I would be grateful if someone can explain me the concept of decorators. I tried to understand it but couldn't.
Upvotes: 2
Views: 200
Reputation: 59681
Think of a decorator as a function that wraps your function.
In math you might have a function f(x)
. If you wrap it with decorator g
you have g(f(x))
.
In python the representation is
@function_g
def function_f():
pass
Here's an example:
def entryExit(f):
def new_f():
print "Entering", f.__name__
f()
print "Exited", f.__name__
return new_f
@entryExit
def func1():
print "inside func1()"
You see we define a function extryExit
which returns a wrapped function (and therefore takes a function as its input). It wraps this function inside of new_f
.
By wrapping the function with the decorator, func1
transforms from
def func1():
print "inside func1()"
to
def func1(f):
print "Entering", f.__name__
print "inside func1()"
print "Exited", f.__name__
You can also write a class to define a decorator, but function decorators are less verbose in my opinion.
You can read more about decorators with this excellent intro here.
Upvotes: 3
Reputation: 19050
Here is an example subset of what you're trying to do:
#!/usr/bin/env python
from __future__ import print_function
def nonnegative(f):
def wrapper(xs):
for x in xs:
if x < 0:
raise ValueError("{} < 0".format(x))
return f(xs)
return wrapper
@nonnegative
def inputs(xs):
for x in xs:
print(x)
inputs([1, 2, 3, 4])
inputs([-1])
Output:
$ python foo.py
1
2
3
4
Traceback (most recent call last):
File "foo.py", line 23, in <module>
inputs([-1])
File "foo.py", line 11, in wrapper
raise ValueError("{} < 0".format(x))
ValueError: -1 < 0
See: https://wiki.python.org/moin/PythonDecorators
PS: I'm not really sure what you were trying to achieve with allCaps
as a decorator so I left this alone since you didn't really use it.
Upvotes: 2