Python: To get proper attribute / function name for dynamically added functions
Question: Below is the sample code.

    
    
    import inspect
    from types import MethodType
    class Settings(object):
        APPS = ['s1', 's2', 's3']
        def __init__(self):
            Settings._setup_apps(self)
    
        @classmethod
        def _setup_apps(cls, instance):
    
            def _setup(self, appname = None):
                print "appname : ", appname
                print "inspect : ", inspect.currentframe().f_code.co_name
    
            for app in Settings.APPS:
                new_attr_name = _setup.__name__[1:] + '_' + app
                setattr(Settings, new_attr_name, _setup)
                # setattr(instance, new_attr_name, MethodType(_setup, instance, type(instance)))
    

Execution

    
    
    s = Settings()
    s.setup_s1()
    

Result

    
    
    appname :  None
    inspect :  _setup
    

How can I get the app name 's1' to be available in the function 'setup_s1'
(similarly 's2' & 's3' in 'setup_s2' & 'setup_s3' respectively), with out
passing the 'appname' explicitly while calling. i.e

    
    
    s.setup_s1('s1') # Do not prefer this
    

But updating the default value of 'appname' from 'None' to 's1' / 's2' / 's3'
during the creation of attribute 'setup_s1' / 'setup_s2' / 'setup_s3' is good.
(I don't know if this is possible).


Answer: You can use
[`functools.partial`](https://docs.python.org/2/library/functools.html#functools.partial)
to bind parameters to a function:

    
    
    import inspect
    import functools
    
    class Settings(object):
        APPS = ['s1', 's2', 's3']
        def __init__(self):
            Settings._setup_apps(self)
    
        @classmethod
        def _setup_apps(cls, instance):
    
            def _setup(self, appname = None):
                print "appname : ", appname
                print "inspect : ", inspect.currentframe().f_code.co_name
    
            for app in Settings.APPS:
                new_attr_name = _setup.__name__[1:] + '_' + app
                setattr(Settings, new_attr_name, functools.partial(_setup, instance, app))
    

