2013-10-13 64 views
1

所以我正在化学项目的乐趣,我有一个函数,从文本文件初始化列表。我想要做的就是让函数用列表代替。因此,这里是我的它第一次尝试,其随机会或不会工作,我不知道为什么:python函数,它自己改变列表

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 

有没有一种办法做这个工作?

+1

不要让函数用列表替换它自己。使用列表和函数是不同的 - 你如何调用列表或切片函数? - 并且试图处理这种情况不同,就像使用代码所显示的那样混乱。此外,“随机”不是一个好的错误描述 - 不吞咽所有例外可能会提供更好的失败指标。 – user2864740

+0

你可能会对[[memoization functions]](http://en.wikipedia.org/wiki/Memoization)感兴趣,但我会这样做:'periodicTable = loadPeriodicTable()'(例如说一次,在程序),因为在这里没有明显需要缓存或记忆。 – user2864740

+0

@ user2864740是的,我想过这样做,但我真的很喜欢探索python的复杂性,这很大程度上是因为这里的一些用户的烦恼。 – Hovestar

回答

5

不要这样做。做正确的事情将是使用,以确保该功能只执行一次,并缓存返回值,一个装饰:

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 TypeError替换毯子except以查看究竟发生了什么。

+0

不错。多一点前期工作,但不易混淆可变默认值。 :) –

+0

@EthanFurman是的,这具有可重复使用并保持原始功能签名的优点。如果只是一个小小的一次性脚本,你的解决方案可能更可取... – l4mpi

+0

Nitpick:它只保留原始签名,因为没有一个;如果有的话,保留它会复杂得多。查看[Michele Simianoto的装饰模块](https://pypi.python.org/pypi/decorator),如果你想看到血淋淋的细节。 –

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 

前两行检查,看看表已经被加载,如果它有它只是返回它。

+1

这不起作用。最后'_table'的赋值不会超出函数范围。相反,列表(最初由'_table'命名)需要修改。 – user2864740

+0

@ user2864740是对的,这应该是'_table。extend(atoms)'或'_table [:] = atoms' - 你不能改变默认参数的引用。 – l4mpi

+0

Woops!你们都是,修正这个...... –