2013-10-13 3 views
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 

방법에 있는가 이거 만들어?

+1

함수를 자체 목록으로 바꾸지 마십시오. 목록과 함수를 사용하는 것은 다릅니다. 어떻게 목록을 호출하거나 함수를 슬라이스합니까? - 그리고이 경우를 다르게 다루려고하면 코드가 사용하는 것처럼 지저분 해집니다. 또한 "무작위로"는 좋은 오류 설명이 아닙니다. 모든 예외 사항을 삼키는 것이 더 나은 오류 표시기를 제공 할 수는 없습니다. – user2864740

+0

''memoization functions ''(http://en.wikipedia.org/wiki/Memoization)에 관심이있을 수 있습니다 :'periodicTable = loadPeriodicTable()'(한 번 말하면, 프로그램) 자신이 여기에 캐싱이나 메모를 할 필요가 없기 때문입니다. – user2864740

+0

@ user2864740 그래, 그 일에 대해 생각했지만, 파이썬의 복잡함을 탐험하는 것을 즐긴다. 여기 몇몇 사용자의 성가심을 많이 받는다. – 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으로 지정되기 전에 예외가 throw되어 결코 대체되지 않기 때문에 이유가 아닌 것 같습니다. try/except 블록을 제거하거나 except 블랭크를 except TypeError으로 바꿔 정확히 무엇이 발생하는지보십시오.

+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! 맞아, 너 둘 다 .. –

관련 문제