A function that creates functions named after arguments passed in
<p>Is there a way to make a function that makes other functions to be called later named after the variables passed in? </p>

<p>For the example let's pretend <a href="https://example.com/engine_list" rel="nofollow">https://example.com/engine_list</a> returns this xml file, when I call it in get_search_engine_xml</p>

<pre><code>&lt;engines&gt;
    &lt;engine address="https://www.google.com/"&gt;Google&lt;/engine&gt;
    &lt;engine address="https://www.bing.com/"&gt;Bing&lt;/engine&gt;
    &lt;engine address="https://duckduckgo.com/"&gt;DuckDuckGo&lt;/engine&gt;
&lt;/engines&gt;
</code></pre>

<p>And here's my code:</p>

<pre><code>import re
import requests
import xml.etree.ElementTree as ET
base_url = 'https://example.com'

def make_safe(s):
    s = re.sub(r"[^\w\s]", '', s)
    s = re.sub(r"\s+", '_', s)
    s = str(s)
    return s

# This is what I'm trying to figure out how to do correctly, create a function
# named after the engine returned in get_search_engine_xml(), to be called later
def create_get_engine_function(function_name, address):
    def function_name():
        r = requests.get(address)
    return function_name

def get_search_engine_xml():
    url = base_url + '/engine_list'
    r = requests.get(url)
    engines_list = str(r.content)
    engines_root = ET.fromstring(engines_list)
    for child in engines_root:
        engine_name = child.text.lower()
        engine_name = make_safe(engine_name)
        engine_address = child.attrib['address']
        create_get_engine_function(engine_name, engine_address)

## Runs without error.
get_search_engine_xml()

## But if I try to call one of the functions.
google()
</code></pre>

<p>I get the following error.</p>

<pre><code>Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
NameError: name 'google' is not defined
</code></pre>

<p>Defining engine_name and engine_address seems to be working when I log it out. So I'm pretty sure the problem lies in create_get_engine_function, which admittedly I don't know what I'm doing and I was trying to piece together from similar questions. </p>

<p>Can you name a function created by another function with an argument that's passed in? Is there a better way to do this?</p>

<p>You can assign them to <a href="https://docs.python.org/3/library/functions.html#globals" rel="nofollow">globals()</a></p>

<pre><code>def create_get_engine_function(function_name, address):
    def function():
        r = requests.get(address)

    function.__name__ = function_name
    function.__qualname__ = function_name  # for Python 3.3+ 
    globals()[function_name] = function
</code></pre>

<p>Although, depending on what you're actually trying to accomplish, a better design would be to store all the engine names/addresses in a dictionary and access them as needed:</p>

<pre><code># You should probably should rename this to 'parse_engines_from_xml'
def get_search_engine_xml(): 
    ...
    search_engines = {} # maps names to addresses
    for child in engines_root:
        ...
        search_engines[engine_name] = engine_address
    return search_engines

engines = get_search_engine_xml()

e = requests.get(engines['google'])
&lt;do whatever&gt;
e = requests.get(engines['bing'])
&lt;do whatever&gt;
</code></pre>

python xml automated-tests