Search code examples
pythonfunctionhandle

Pulling labels for def defined functions from a list of strings in python


I would like to create functions using the normal def procedure in Python with labels assigned to the namespace that are pulled from a list of strings. How can this be achieved?

Motivation for this question: I am creating a library of python functions, compatible with sympy, to be used by mathematicians for symbolic computational experimentation. Many of the functions need to initialize a system of several objects with related labels, respectively generated by some user-provided string. To generate these labels, I build a list of strings from the user provided string. Then I proceed to assign labels from this list of strings to the various objects that are being defined, typically by updating the globals() dict directly. Some of the objects being defined however are functions themselves, which is the reason for this question.

A concrete example: one function should allow users to initialize variables with whichever labels they want and simultaneously initialize objects representing coordinate vector fields dual to those variables (which we would define as functions in python). The user should specify labels for their variables and then the function should generate related labels for the vector field objects. E.g., if the user chooses the variable label ‘x’ then the function should automatically label the created vector field object ‘D_x’. This is just one of many examples where I need to implement such a construction, which is why this question is posed in its present generality.

An example problem: given an arbitrary list of strings exampleList=['label1','label2','label3',...] of length k, initialize k def defined functions of the form

exampleList=['label1','label2','label3','label4']
def label1(arg: str):
    if len(arg)>exampleList[0]
        print('the word '+arg+' has more letters than the word '+exampleList[0])
def label2(arg: str):
    if len(arg)>exampleList[1]
        print('the word '+arg+' has more letters than the word '+exampleList[1])
# ...etc.

programmatically.

If the functions to be defined only involve operations implementable within lambda functions, then this can be done with lambda functions by updating the globals() dict. E.g., one can write something like

exampleList=['label1','label2','label3']
exampleOperation= lambda j,k: len(j)-len(k)
globals().update(zip(exampleList,[lambda k:exampleOperation(j,k) for j in exampleList]))

The above example initialized some lambda functions with labels assigned from the list exampleList. I would, however, like to accomplish the analogous task with normal def defined functions rather than lambda functions.


Solution

  • you could use a class with a factory function

    class MyLabels:
    
        def __init__(self, label_list):
            for label in label_list:
                setattr(self, label, self.label_factory(label))
    
        def label_factory(self, label):
            def my_func(arg: str):
                if len(arg) > len(label):
                    print(f'the word {arg} has more letters than the word {label}')
            return my_func
    
    exampleList=['label1','label2','label3','label4']
    ml = MyLabels(exampleList)
    ml.label1('stackoverflow') #the word stackoverflow has more letters than the word label1