有没有办法创建一个函数,使得稍后以传入的变量命名的其他函数被调用?
这个示例让我们假装https://example.com/engine_list返回此xml文件,当我在get_search_engine_xml中调用它时
<engines>
<engine address="https://www.google.com/">Google</engine>
<engine address="https://www.bing.com/">Bing</engine>
<engine address="https://duckduckgo.com/">DuckDuckGo</engine>
</engines>
这是我的代码:
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()
我收到以下错误。
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'google' is not defined
当我将其注销时,定义engine_name和engine_address似乎正在工作。所以我很确定问题在于create_get_engine_function,我承认我不知道自己在做什么,而且我试图从类似的问题拼凑起来。
您是否可以使用传入的参数命名由另一个函数创建的函数?有更好的方法吗?
答案 0 :(得分:2)
您可以将它们分配到globals()
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
虽然,根据您实际想要完成的任务,更好的设计是将所有引擎名称/地址存储在字典中并根据需要访问它们:
# 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'])
<do whatever>
e = requests.get(engines['bing'])
<do whatever>