Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
212 views
in Technique[技术] by (71.8m points)

python - Programmatically create function specification

For my own entertainment, I was wondering how to achieve the following:

functionA = make_fun(['paramA', 'paramB'])
functionB = make_fun(['arg1', 'arg2', 'arg3'])

equivalent to

def functionA(paramA, paramB):
    print(paramA)
    print(paramB)

def functionB(arg1, arg2, arg3):
    print(arg1)
    print(arg2)
    print(arg3) 

This means the following behaviour is required:

functionA(3, paramB=1)       # Works
functionA(3, 2, 1)           # Fails
functionB(0)                 # Fails

The focus of the question is on the variable argspec - I comfortable creating the function body using the usual decorator techniques.

For those that are interested, I was playing around with trying to programmatically create classes like the following. Again the difficulty is in generating the __init__ method with programmatic parameters - the rest of the class appears straightforward using a decorator or maybe a metaclass.

class MyClass:
    def __init__(self, paramA=None, paramB=None):
        self._attr = ['paramA', 'paramB']
        for a in self._attr:
            self.__setattr__(a, None)

    def __str__(self):
        return str({k:v for (k,v) in self.__dict__.items() if k in self._attributes})
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can use exec to construct the function object from a string containing Python code:

def make_fun(parameters):
    exec("def f_make_fun({}): pass".format(', '.join(parameters)))
    return locals()['f_make_fun']

Example:

>>> f = make_fun(['a', 'b'])
>>> import inspect
>>> print(inspect.signature(f).parameters)
OrderedDict([('a', <Parameter at 0x1024297e0 'a'>), ('b', <Parameter at 0x102429948 'b'>)])

If you want more functionality (e.g., default argument values), it's a matter of adapting the string that contains the code and having it represent the desired function signature.

Disclaimer: as pointed out below it's important that you verify the contents of parameters and that the resulting Python code string is safe to pass to exec. You should construct parameters yourself or put restrictions in place to prevent the user from constructing a malicious value for parameters.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...