I made a decorator that would modify a class so that any method other than init or class would print "Hello World" before running. The issue is I keep getting an unexpected error message when I inherit from dict. What does it mean and how do I solve it?
Code
from functools import wraps
# Print hello world when any method is called
def hello_world(cls):
for attr in dir(cls):
# Only modify methods that aren't init or class
if not callable(getattr(cls, attr)) or any([method in attr for method in ["init", "class"]]):
continue
old_method = getattr(cls, attr)
# Modify method to print "Hello World" before running
@wraps(getattr(cls, attr))
def new_method(self, *args, **kwargs):
print("Hello World!")
return old_method(self, *args, **kwargs)
# Update class with modified method
setattr(cls, attr, new_method)
return cls
@hello_world
class Custom(dict):
pass
dictionary = Custom()
dictionary["Key"] = "Value"
print(dictionary)
Output
Hello World!
Traceback (most recent call last):
File "", line 22, in
dictionary = Custom()
File "", line 12, in new_method
return old_method(self, *args, **kwargs)
TypeError: descriptor 'values' for 'dict' objects doesn't apply to a 'type' object
or method in ('__init__','__class__')in yourifstatement. That doesn't fix the error, however. - Tim Robertsold_methodin your inner function. By the time you're done, all of thenew_methodinstances are referring to theold_valuein the function, which finishes withvalues(alphabetically). That is, ALL of the functions will now callvalues. - Tim Robertsold_methodvalue not being captured. Based on that insight, I was able to create a workaround for the problem. See my posted answer. - Tom Karzes