2

I already have a class poly(), and a method get_function()

class poly():
    def __init__(self,n):
        func = ''
        var = []
        for i in range(n + 1):
            func += ('k'+str(i)) + ' * '+ 'x ** ' + str(i) + ' + '
            var.append('k'+str(i))
        func = func[:-3]

        self.func_str = func
        self.var = var
        siglist = var.copy()
        siglist.append('x')
        self.siglist = tuple(siglist)

    def get_function(self, *args):
        return eval(self.func_str)

Now what I want to do is to pass self.siglist to signature of get_function for future usage(scipy.optimize.curve_fit needs __signature__ to do curve fitting)

I ran

pol = poly(2)
inspect.signature(pol.get_function)

It shows that the signature of that function is <Signature (*args)>

But I want to change signature from *args to k0, k1, x(Stored in tuple siglist)

What I found in Python Cookbook is:

from functools import wraps
import inspect
def optional_debug(func):    
    @wraps(func)    
    def wrapper(*args, debug=False, **kwargs):             
            return func(*args, **kwargs)
    sig = inspect.signature(func)    
    parms = list(sig.parameters.values())  
    # what is inspect.Parameter.KEYWORD_ONLY do ?
    parms.append(inspect.Parameter('debug', inspect.Parameter.KEYWORD_ONLY, default=False))    
    wrapper.__signature__ = sig.replace(parameters=parms)   
    return wrapper 

@optional_debug
def test(input):
    pass

print(inspect.signature(test)) 

This function is able to change the signature of a function, the result is:

(input, *, debug=False)

How to pass self.siglist to edit the signature if I put the decorator outside the class, and why is there a * in the signature after using a decorator to change it?

________________To edit the __signature__ if a function is not in a class___________

def make_sig(*names):
    parms = [Parameter(name, Parameter.POSITIONAL_OR_KEYWORD)
            for name in names]
    return Signature(parms)

def test():
    pass
ls = ('a','b')
test.__signature__ = make_sig(*ls)
inspect.signature(test)

get:

<Signature (a, b)>

But What about it inside a class?

Yiling Liu
  • 666
  • 1
  • 6
  • 21
  • To answer your two direct questions: 1. you can't (`siglist` is only known on instantiation, and decorators are invoked at definition time); and 2. because you asked for debug to be keyword-only, see e.g: https://stackoverflow.com/questions/14301967/bare-asterisk-in-function-arguments. – jonrsharpe Dec 20 '19 at 08:38
  • This might help you: https://stackoverflow.com/questions/1409295/set-function-signature-in-python – Amiram Dec 20 '19 at 10:48

0 Answers0