Create a decorator expected_type() that checks if what the decorated function returns is of expected type. An UnexpectedTypeException should be raised if the type returned by the decorated function doesn’t match the ones expected.
Requirements:
expected_type() should accept a tuple of many types that may be valid
UnexpectedTypeException should be raised if decorated function returns object of type that wasn’t defined in expected_type() 's arguments (you have to implement that class)
return_something will be decorated with expected_type in the tests and will look exactly like in the example below
#the decorator creation
def expected_type(*msg):
def wrapper(return_something):
for items in msg:
x = return_something()
if items == type(x):
print("hello function is of the type expected")
else:
print("Type Unexpected Error")
break
return wrapper
@expected_type('str','dict','set','list')
def return_something():
return ('hello everyone')
# calling the function
print(return_something)
The Error l am getting is:
Type Unexpected Error
None
I am expecting the code to print hello function is of the type expected but it is not working, how can l correct it?
ok l have started to get what l want now, why am l getting None at the end?, my return_something function has a return statement
#the decorator creation
def expected_type(*msg):
def wrapper(return_something):
for items in msg:
x = return_something()
if items == type(x):
print("hello function is of the type expected")
break
else:
print("Type Unexpected Error")
return wrapper
@expected_type(str,dict,set,list)
def return_something():
return ('hello everyone')
# calling the function
print(return_something)
That’s not how you compare an item to a list.
For a start, a for loop will run a set number of times. If you give it 4 items, it will run up to 4 times - think about in what situation it would run 4 times and what it would put out.
And when you are finished and before you rethink everything, just use “if-in”, because that’s the Python way of doing this.
Jumping off @sanity’s comment, I think you are not getting the result you expect because things are not being called when you expect them. You can use a Python REPL to run your code in 3 steps (defining expected_type, defining return_something, and calling return_something), in order to see when exactly things are happening. Is wrapper being ran when return_something is called or during the definition of it?
#the decorator creation
def expected_type(*msg):
def wrapper(return_something):
for items in msg:
x = return_something()
if items == type(x):
print("hello function is of the type expected")
break
else:
print("Type Unexpected Error")
return wrapper
@expected_type(str,dict,set,list)
def return_something():
return ('hello everyone')
# calling the function
return_something()
In line 25 of the code l am getting error that:
TypeError: ‘NoneType’ object is not callable
Why does this error come up when the return something function returns something?
@kylec You are right about what you said, how do l run the code in 3 steps using the REPL
expected_type(str,dict,set,list) returns wrapper, so it’s:
return_something = wrapper(return_something)
So at the end return_something is whatever is returned by wrapper after passing it return_something function. Questions for this arises - what wrapper returns and can it be called, so we can still write return_something().
Ok I understand now, when l was looking at decorators, I also found this piece of code, that is almost the same in the structure, like inside the wrapper function
# defining a decorator
def hello_decorator(func):
# inner1 is a Wrapper function in
# which the argument is called
# inner function can access the outer local
# functions like in this case "func"
def inner1():
print("Hello, this is before function execution")
# calling the actual function now
# inside the wrapper function.
func()
print("This is after function execution")
return inner1
# defining a function, to be called inside wrapper
def function_to_be_used():
print("This is inside the function !!")
# passing 'function_to_be_used' inside the
# decorator to control its behaviour
function_to_be_used = hello_decorator(function_to_be_used)
# calling the function
function_to_be_used()