1

これは些細な質問であることはわかっていますが、さまざまな方法を試し、解決策を少し探しましたが、現在のモジュールでサブ関数を作成して参照するにはどうすればよいですか?

たとえば、テキスト ファイルを解析するプログラムを作成しており、その中の 300 の異なる名前のそれぞれについて、カテゴリに割り当てたいと考えています。

これらは300あり、辞書を作成するために構造化されたこれらのリストがあるため、形式はlookup [key] = valueです(ボーナス質問;大量の辞書よりも効率的または賢明な方法はありますか?)。

これをすべて同じモジュールに保持したいのですが、ファイルの最後に関数(辞書の初期化など)があるため、コードを表示するために300行下にスクロールする必要はありません。つまり、次のようにレイアウトされています以下の例。

以下のように実行すると、「initlookups が定義されていません」というエラーが表示されます。私が構造化すると、初期化、関数定義、関数使用、問題ありません。

コードをインラインに保持せずに関数と関連する dict を初期化する明白な方法があるに違いないと確信していますが、これまでにかなりの数を試しましたが成功しませんでした。外部モジュールに入れてこれをインポートすることはできますが、簡単にするためにそうしないことをお勧めします。

モジュール構造に関して何をすべきですか?このルックアップ テーブルを格納するために dict を使用するよりも良い方法はありますか (約 10 のカテゴリにマッピングされた 300 の一意のテキスト キーですか?

ありがとう、

ブレンダン


import ..... (initialisation code,etc )

initLookups()          # **Should create the dict - How should this be referenced?**
print getlookup(KEY)   # **How should this be referenced?**


def initLookups():
    global lookup
    lookup={}
    lookup["A"]="AA"
    lookup["B"]="BB"
    (etc etc etc....)


def getlookup(value)
    if name in lookup.keys():
        getlookup=lookup[name]
    else:
        getlookup=""

    return getlookup
4

4 に答える 4

5

関数は、呼び出す前に定義する必要があります。実行する必要があるコードをファイルの先頭に配置したい場合は、main関数を定義して末尾から呼び出すだけです。

import sys

def main(args):
    pass

# All your other function definitions here

if __name__ == '__main__':
    exit(main(sys.argv[1:]))

このようにして、参照するものはすべてmain解析されているため、すでに認識されています。テストの理由__name__は、この方法ではmain、スクリプトが別のファイルによってインポートされた場合ではなく、スクリプトが直接実行された場合にのみメソッドが実行されるためです。


補足: dict300 個のキーを持つ a は決して大規模ではありませんが、 を満たすコードをdict別のモジュールに移動するか、(おそらくもっと派手な) キーと値のペアをJSONなどの形式で保存してロードすることをお勧めします。プログラムの開始時。

于 2009-05-29T09:04:40.753 に答える
1

これを行うためのよりPython的な方法を次に示します。ところで、多くの選択肢はありません。

関数は、使用する前に定義する必要があります。限目。

ただし、コンパイラの利益のためにすべての関数を厳密に順序付ける必要はありません。関数の実行を最後に置く必要があるだけです。

import # (initialisation code,etc )

def initLookups(): # Definitions must come before actual use
    lookup={}
    lookup["A"]="AA"
    lookup["B"]="BB"
    (etc etc etc....)
    return lookup

# Any functions initLookups uses, can be define here.
# As long as they're findable in the same module.

if __name__ == "__main__": # Use comes last
    lookup= initLookups() 
    print lookup.get("Key","")

関数は必要ないことに注意してください。これは、 getgetlookupという名前の dict の組み込み機能です。

また、「初期化コード」も怪しい。インポートは何も「実行」してはなりません。関数とクラスを定義する必要がありますが、実際に実行可能なコードは提供しません。長期的には、インポートによって処理される実行可能コードは、メンテナンスの悪夢になる可能性があります。

最も注目すべき例外は、デフォルトで作成されるモジュール レベルの Singleton オブジェクトです。その場合でも、モジュールを機能させる謎のオブジェクトがドキュメントで明確に識別されていることを確認してください。

于 2009-05-29T10:34:29.417 に答える
0

名前をフラットなテキスト ファイルに保持し、実行時にロードすることは、良い代替手段になると思います。私は、プレーン テキストから始めて RDMS に至るまで、自分のデータを可能な限り複雑にしないようにしています (このアイデアはThe Pragmatic Programmerから引用しました)。

辞書は Python で非常に効率的です。それは本質的に、言語全体が構築されているものです。300 項目は、健全な dict の使用範囲内です。

名前.txt:

A = AAA
B = BBB
C = CCC

getname.py:

import sys

FILENAME = "names.txt"

def main(key):
    pairs = (line.split("=") for line in open(FILENAME))
    names = dict((x.strip(), y.strip()) for x,y in pairs)
    return names.get(key, "Not found")

if __name__ == "__main__":
    print main(sys.argv[-1])

なんらかの理由で本当にすべてを 1 つのモジュールに保持したい場合は、モジュールの上部に文字列を貼り付けることができます。大量のテキストは、辞書の初期化コードの巨大な混乱よりも気を散らすことが少ないと思います(そして後で編集するのが簡単です):

import sys

LINES = """
A = AAA
B = BBB
C = CCC
D = DDD
E = EEE""".strip().splitlines()

PAIRS = (line.split("=") for line in LINES)
NAMES = dict((x.strip(), y.strip()) for x,y in PAIRS)

def main(key):
    return NAMES.get(key, "Not found")

if __name__ == "__main__":
    print main(sys.argv[-1])
于 2009-05-31T23:43:14.163 に答える
0

ルックアップ dict が変更されていない場合、最も簡単な方法は、それをモジュール スコープ変数にすることです。すなわち:

lookup = {
    'A' : 'AA',
    'B' : 'BB',
    ...
}

変更を加えて後で再初期化する必要がある場合は、初期化関数でこれを行うことができます。

def initLookups():
    global lookup
    lookup = {
        'A' : 'AA',
        'B' : 'BB',
        ...
    }

(または、lookup.update({'A':'AA', ...}) を使用して辞書をその場で変更し、古いバインディングにアクセスできるすべての呼び出し元に影響を与えます。)

ただし、これらのルックアップを何らかの標準形式で取得している場合は、単純にファイルから読み込んで、そこから辞書を作成する方が簡単な場合があります。

必要に応じて機能を配置できます。順序付けに関する唯一の規則は、関数が呼び出された時点でアクセスされる変数が存在している必要があるということです。実際にその関数を使用しようとするものが何もない限り、関数がまだ存在していない本体内の変数への参照を持っていても問題ありません。すなわち:

def foo():
    print greeting, "World"  # Note that greeting is not yet defined when foo() is created

greeting = "Hello"

foo() # Prints "Hello World"

しかし:

def foo():
    print greeting, "World"

foo()              # Gives an error - greeting not yet defined.
greeting = "Hello"

注意すべきもう 1 つの点: getlookup 関数は非常に非効率的です。" if name in lookup.keys()" を使用すると、実際には dict からキーのリストを取得し、このリストを繰り返し処理して項目を見つけます。これにより、辞書が与えるパフォーマンス上の利点がすべて失われます。代わりに、" " はこれを回避するか、キーがディクショナリにない場合に返されるデフォルトを指定できるif name in lookupという事実を使用します。.get

def getlookup(name)
    return lookup.get(name, "")
于 2009-05-29T10:32:39.373 に答える