2013-10-13 63 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!你們都是,修正這個...... –