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

不要那样做。正确的做法是使用装饰器来确保函数只执行一次并缓存返回值:

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块或更换毯子exceptexcept 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

前两行检查表是否已经加载,如果已经加载,则简单地返回它。

于 2013-10-13T19:05:40.870 回答