Search code examples
pythonpython-3.xmetaprogrammingcode-generationpython-decorators

Python function which returns its own signature with parameters


Marked as solved because: The solved solution provides a good-enough solution to the problem, even though it doesn't quite solve the problem of dynamically generating the function name on-demand.

I want to generate a function which returns its own signature with parameters. Is this possible in Python? So, the function gets generated by the call itself, and returns the string which represents its own name and parameters.

Here is a simple example of what I am looking for:

class Object(object):
  #Impl here?
  pass

a = Object()
returned_string = a.foo(param1 = 1, param2 = "cheese")

print(returned_string)
#should print: a.foo(param1 = 1, param2 = "cheese")
#or     print:   foo(param1 = 1, param2 = "cheese")

Important, foo is an arbitrary name and should not be "hard-coded" but generated.

The code should allow for the following:

 print(a.doodle(param1 = 32)) #prints: doodle(param1 = 32)
 print(a.bar(param42 = "pi")) #prints: bar(param42 = "pi")

without defining further functions.

Thanks :)


Solution

  • You should be able to do what you want using **kwargs. As an example:

    def my_args_are(**kwargs):
        return "my_args_are({})".format(
            ", ".join("{0} = {1!r}".format(arg, val)
                for arg, val in kwargs.items()))
    

    It works:

    >>> my_args_are(param1 = 1, param2 = "cheese")
    "my_args_are(param1 = 1, param2 = 'cheese')"
    

    If you don't want to hardcode the name you can use inspect:

    import inspect
    
    def my_args_are(**kwargs):
        fname = inspect.currentframe().f_code.co_name
        argstr = ", ".join("{0} = {1!r}".format(arg, val)
                           for arg, val in kwargs.items()))
        return "{}({})".format(fname, argstr)