2016-09-05 14 views
0

変数を渡した後に他の関数を後で呼び出す関数を作成する方法はありますか?渡された引数の名前の関数を作成する関数

たとえば、私は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> 

でそれを呼び出し、ここに私のコードだときのは、このxmlファイルhttps://example.com/engine_listリターンをふりましょう:

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にあると確信しています。それは、私が何をしているのか分からず、同様の質問からまとめようとしていました。

渡された引数を持つ別の関数によって作成された関数の名前を付けることはできますか?これを行うより良い方法はありますか?

+1

最終目標は何ですか? –

+0

基本的に、アプリはユーザーの入力を受け取り、物事を行います。入力は、これらの関数のいずれかを名前で呼び出し、他の静的関数といっしょに呼び出すなど、何をすべきかを把握するためのスイッチ関数に入ります。後でget_search_engine_xml()をもう一度呼び出す必要があり、xmlが変更された関数を削除したり、返されたxmlに基づいて新しい関数を追加したりする必要があります。 – Cynic

答えて

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> 
+0

私はおそらく、 'get_search_engine_xml()'とグローバルの両方から検索エンジンを返すでしょう。 – AChampion

+0

@AChampion私は同意する、それは良いだろう。私はあなたの提案を取り入れました。 –

+0

超高速リプレイ@friendlydogと改良AChampionをありがとう。サンプルコードを使ってローカルXMLファイルをロードしても動作しているので、私のコードを少し気にしてみましょう。しかし、私が作業しているものを直ちに修正しませんでした。おそらく私の悪いですが、私が間違っている場合に備えてそれを働かせたいと思っています。しかし、間違いなく、引数に基づいた関数によって作成された関数の名前付けの方法の問題の中核にはっきりと答えました。 – Cynic

関連する問題