2011-08-29 2 views
2

단일 파일/디렉토리 또는 파일/디렉토리 목록 일 수있는 인수의 크기 합계를 반환하는 함수가 아래에 나와 있습니다. 이 코드는 오류 메시지 RuntimeError: maximum recursion depth exceeded while calling a Python object을 표시하지만 테스트 해 보려고합니다.Python : 최대 재귀 깊이

해결 방법?

감사

수레 쉬

#!/usr/bin/python3.1 
import os 

def fileSizes(f): 
    if hasattr(f,'__iter__'): 
     return sum(filter(fileSizes,f)) 
    if os.path.isfile(f): 
     return os.path.getsize(f) 
    elif os.path.isdir(f): 
     total_size = os.path.getsize(f) 
     for item in os.listdir(f): 
      total_size += fileSizes(os.path.join(f, item)) 
     return total_size 
+0

listdir에 현재 디렉토리가 포함되어 있습니까? 반복하는 iterables는 무엇입니까? –

+0

'os.listdir()'은 현재 또는 부모 디렉토리를 포함하지 않습니다. – suresh

답변

1

문제는 일치한다 : f 이후

if hasattr(f,'__iter__'): 
    return sum(filter(fileSizes,f)) 

는 경로, 그것은 문자열이며, 속성 __iter__이있다, 그래서 당신 루프가 무한히.

+0

아, 그렇다면 문자열에 유효하지 않은 목록을 테스트하려면 어떻게해야합니까? 좋아, 내가 믿는 isinstance()를 사용할 수 있습니다 .... – suresh

+0

그게 문제를 해결 했습니까? 두 번째 질문에 대해서는'type (f)! = str and hasattr (f, '__ iter __')'를 시도 할 수 있습니다 ... ... –

+0

@rm'isinstance'를 사용했습니다. 재귀 문제는 없어졌지만'sum (filter (...)) '은 다른 종류의 에러를 내고 있습니다 ... – suresh

2

지난번에 내가는 기본 최대 재귀 깊이 당신은 몇 가지 옵션이 1000이었다에는 재귀 제한을 부과하지

  1. 사용 Stackless Python을 (무한 재귀를 허용).
  2. 재귀 적이 아닌 반복 스타일로 함수를 다시 작성하면 처음부터 스택 오버플로가 발생하지 않습니다.
  3. sys.setrecursionlimit으로 최대 재귀 제한을 설정하십시오. 학대 당하면 세분화 오류가 발생할 수 있음을 유의하십시오.
+0

-1 : 프로그램에서 sys.setrecursionlimit을 설정하면 안전하지 않으며 segfault가 발생할 수 있습니다. 그 때가 올바른 유일한 시간은 일회용 스크립트를 작성할 때뿐입니다. :/ –

+2

@Devin이 내가 그에게 옵션이라고 말할 수 없다는 것을 의미하지는 않습니다. –

+0

@Devin은 쓰는 모든 C 프로그램이 "잠재적으로 segfaulting"이기 때문에 결코 C를 사용하지 않아야합니다. 기분이 나아진다면 주문을 전환하고 경고를 추가하겠습니다. –

1

깊은 재귀와 관련된 문제를 피하는 데는 많은 트릭이 있지만 핵심 문제는 아니라고 생각됩니다. (아마도 아주 깊은 디렉토리 구조를 가지고 있기 때문에 얕은 디렉토리에서 먼저 테스트해야합니다.)

링크로 인해 디렉토리 트리에서주기적인 구조를 찾은 것 같습니다. 즉, 심볼릭 링크 된 디렉토리는 부모 디렉토리를 다시 가리 킵니다. (구조의이 종류는 특별하지 않다).

다음에 오기 전에 디렉토리가 심볼릭 링크인지 여부를 확인하여 무한 루프를 피할 수 있습니다.

또 다른 확실성은 당신이 " 또는 ".."귀하의 목록 어딘가에. 또한 무한 루프가 생성됩니다. 나는 여기서 그런 일이 일어나지 않는다고 생각하지만 그럴 가치가 있습니다. os.listdir이 반환하지 않는 것 같습니다.

+0

@Anderson, 얕은 디렉토리에서 실행을 시도했지만 인수에 관계없이 코드에서 동일한 오류 메시지가 표시됩니다. 그래서 지금은 테스트 할 수 없습니다 ... – suresh

+0

내 디렉토리에서 코드를 "있는 그대로"실행하면 결과가 생성됩니다. 특히 두 개의 디렉토리에서'fileSize (".")'를 시도했습니다. 그러나 결과는 틀린 것처럼 보입니다. (예를 들어 빈 디렉토리에서 실행될 때 나는 68을 얻습니다.) –

8

adhoc 디렉터리 - 횡단 방법을 직접 작성하는 대신 기본 제공 os.walk(Documentation) 메서드를 사용하십시오.

사실 위의 문서 (위 링크)의 예는 비 디렉토리 파일의 전체 크기를 계산합니다.

+0

하지만'os.walk()'는'listdir()'을 차례로 호출합니까? 위의 코드에서'listdir()'을 사용하고 있습니다. 그렇다면 여전히 adhoc이라고 할 수 있습니까? – suresh

+0

'os.walk'는'os.listdir()'을 호출합니다. 이것은 당신의 코드와 같은 방식으로 동작하지만, 반복적으로 그리고 또한 심볼릭 링크를 따르거나 무시할 수 있습니다. 실제로 문서를 살펴 봐야합니다. 모든 것이 분명합니다. – Can

관련 문제