I am trying to retrieve the import-string in a decorated @classmethod
to register this string in an pipeline system. But when I'm inspecting the function object in the decorator function a cannot find any information about the class object or the class name.
So the code looks something like this:
def import_string_decorator(**opt_kwargs):
def wrap(f):
# Here is the problem
if inspect.ismethod(f):
class_name = f.im_self.__name__
import_string = f.__module__ + "." class_name + "." + f.__name__
# But this doesn't work because f no longer is a <bound method to class 'SomeClass'> but is a regular <function>
else:
import_string = f.__module__ + "." + f.__name__
# Register the string
do_something(import_string, **opt_kwargs)
def wrapped_f(*args, **kwargs):
f(*args, **kwargs)
return wrapped_f
return wrap
# Decorated Class
opt_dict = {"some": "values"}
class SomeClass(object):
@classmethod
@import_string_decorator(**opt_dict)
def double_decorated_function(cls, *args, **kwargs):
pass
But I haven't found a way to retrieve the class object of the decorated function. The inspect.ismethod()
function also returns False
because it checks isinstance(types.MethodType)
underneath.
What you want cannot be done with function decorators. The function object is created and decorated before the class object is built. Python executes the class body first, and the resulting names then form the class attributes.
Binding of methods then takes place dynamically, as you access the name as an attribute, using the descriptor protocol.
You need to hook into class creation for you to get access to the class name; you can use a class decorator, or use a metaclass. You can combine these techniques with function decorators if that makes it easier:
@registered_class
class SomeClass(object):
@classmethod
@import_string_decorator(**opt_dict)
def double_decorated_function(cls, *args, **kwargs):
pass
where the import_string_decorator
could annotate the function (you can set an attribute on it, for example) for the registered_class
decorator to inspect when the class is being decorated.