1

私は楽しみのために化学プロジェクトに取り組んでおり、テキスト ファイルからリストを初期化する関数を持っています。私がやりたいことは、関数がそれ自体をリストに置き換えるようにすることです。だから、これが私の最初の試みで、ランダムに機能するか機能しないかを示しています。理由はわかりません。

def periodicTable():
    global periodicTable
    tableAtoms = open('/Users/username/Dropbox/Python/Chem Project/atoms.csv','r')
    listAtoms = tableAtoms.readlines()
    tableAtoms.close()
    del listAtoms[0]
    atoms = []
    for atom in listAtoms:
        atom = atom.split(',')
        atoms.append(Atom(*atom))
    periodicTable = atoms

次の方法で呼び出されます。

def findAtomBySymbol(symbol):
    try:
        periodicTable()
    except:
        pass
    for atom in periodicTable:
        if atom.symbol == symbol:
            return atom
    return None

これを機能させる方法はありますか?

4

2 に答える 2

4

そうしないでください。正しいことは、関数が 1 回だけ実行され、戻り値がキャッシュされることを保証するデコレータを使用することです。

def cachedfunction(f):
    cache = []
    def deco(*args, **kwargs):
        if cache:
            return cache[0]
        result = f(*args, **kwargs)
        cache.append(result)
        return result
    return deco

@cachedfunction
def periodicTable():
    #etc

とはいえ、関数が呼び出された後に関数自体を置き換えることを妨げるものは何もないため、通常はアプローチが機能するはずです。periodicTableそうでない理由は、結果を代入する前に例外がスローされ、置き換えられないためだと思います。ブロックを取り外すtry/exceptか、ブランケットexceptを交換して、except TypeError正確に何が起こるかを確認してください。

于 2013-10-13T19:05:22.190 に答える
3

これは非常に悪い習慣です。

より良いのは、関数が既にテーブルをロードしているかどうかを記憶させることです。

def periodicTable(_table=[]):
    if _table:
        return _table
    tableAtoms = open('/Users/username/Dropbox/Python/Chem Project/atoms.csv','r')
    listAtoms = tableAtoms.readlines()
    tableAtoms.close()
    del listAtoms[0]
    atoms = []
    for atom in listAtoms:
        atom = atom.split(',')
        atoms.append(Atom(*atom))
    _table[:] = atoms

最初の 2 行は、テーブルが既にロードされているかどうかを確認し、ロードされている場合は単純にそれを返します。

于 2013-10-13T19:05:40.870 に答える