2012-11-29 1 views
1

입력 인자의 라인을 반복 처리하지만 문자열이나 파일과 같은 객체를 받아 들일 수있는 파이썬 함수를 작성하고 싶다. 이것을 할 수있는 방법이 있습니까?필자는 파이썬 함수를 사용하여 행을 반복한다. 문자열이나 파일과 같은 객체를 받아 들인다.

def myfunc(x): 
    for line in x: 
     doSomething(line) 

위의 코드는 문자열을 파일 - 류의 객체에 대한 아니라 작동하고, 내 진짜 작업이 위보다 훨씬 더 복잡하기 때문에 차라리 두 개가 아닌 하나의 함수를 작성할 것입니다.

답변

2

만 변형에 대해 당신은 여기가 사용할 수 있습니다 try-except

def myfunc(x): 
    try: 
     x = x.splitlines(True) 
    except AttributeError: 
     pass #likely a file 

    for line in x: 
     doSomething(line) 

또 다른 버전 (약간 덜 허용 - 주석 참조)

try: 
    from cStringIO import StringIO 
except ImportError: #python 3 
    from io import StringIO 

def myfunc(x): 
    try: 
     x.seek(0) 
    except AttributeError: #likely a string 
     x = StringIO(x) 

    for line in x: 
     doSomething(line) 
+1

필자는 파일과 같은 객체를 테스트하지 않을 것입니다. 이제는 파일과 읽기 버퍼 ('StringIO'가 소비 할 수있는 것)로 제한되었습니다. 차라리 iterator (hasattr (x, 'next')'또는'try : iter (x)','except TypeError :')를 테스트 할 것입니다. –

+0

'iter ("foo")'와 iter (open ('file.txt'))'모두 작동합니다. 나는'hasattr (x, 'next')'를 사용할 수 있다고 생각한다. 어쨌든, OP의 try/except 모양은 API가 실제로 무엇을 보여야하는지에 달려 있습니다. OP는 문자열과 파일 객체를 말한 것뿐입니다. 이를 문자열, 파일 객체 및 기타 iterables로 확장하려면 항상 첫 번째 버전을 사용할 수 있습니다. 여기에 가능성은 다양한 제한/허용 범위 (이는 내가 그것을 입증하는 2 가지 옵션을 게시 한 이유의 일부 임)에 따라 끝이 없습니다. – mgilson

+0

받아 들였습니다 - 여기에 여분의 닦는 것은 내가 몰랐던'splitlines (True)'의 사용이었습니다. 이것은 파일과 같은 객체의 문자열과 행 사이의 동작을 근본적으로 동일하게 만듭니다. –

1

문자열에서도 작동하지만 문자 단위로 문자열을 반복합니다. 사용자는 문자열 대신 목록을 사용하여 함수를 호출해야합니다.

명시 적으로 다음 라인으로 해석되도록, 하나의 문자열을 전달 지원하려는 경우 해당 테스트해야합니다 :

def myfunc(x): 
    if isinstance(x, basestring): 
     # Interpret argument as one line 
     x = [x] 
    for line in x: 
     doSomething(line) 

을 다른 방법으로, 줄 바꿈에 문자열을 분할 수 대신 :

def myfunc(x): 
    if hasattr(x, 'splitlines'): 
     # Interpret argument as multiple lines: 
     x = x.splitlines() 
    for line in x: 
     doSomething(line) 
+1

'isinstance (x, basestring)'? –

+0

@JonClements : 소개되었을 때 확신 할 수 없었습니다. :-) –

+0

'03/'04에 대하여 ... –

4

사용 오리 입력 :

def myfunc(x): 
    try: 
     lines = x.split('\n') 
    except AttributeError: 
     lines = x 
    for line in lines: 
     doSomething(line) 

당신은 또한 유형을 확인하실 수 있습니다 당신이 원하는 경우 :

def myfunc(x): 
    if isinstance(x, basestring): # will work in Python >=2.3, <3.x 
     lines = x.split('\n') 
    else: 
     lines = x 
    for line in lines: 
     doSomething(line) 
+0

*은 Python 2.x *에서 작동합니다 : Python 2.3 및 사실. –

+0

@MartijnPieters : 감사합니다.단지 부수적으로 말하지만, 파이썬에서 실행중인 많은 활성 애플리케이션들이 얼마나 많은지 궁금하다. 지금은 9.5 세입니다. – Tadeck

+0

Zope 설치 중 일부를 알고 있습니다. –

1

방금 ​​파일 - 류의 객체를 받아 들인다면, 당신은 StringIO에 문자열 인수를 포장 발신자를 지시 할 수 있습니다 :

myfunc(StringIO(s)) 
0

isinstance (var, str) var가 str 유형인지 확인합니다.

파일 형식을 직접 기억하지 못했지만 파일 var을 사용하여 찾을 수 있습니다. 그것은

당신은 사용할 수 있습니다 ...> <에 표시됩니다 :

def myfunc(x): 
    for line in x: 
     if isinstance(line, str): 
      print line 
     else: 
      # Its a file so do file things 
0

한 가지 방법은 x가 문자열 인 경우 결정하기 위해 isinstance 같은 것을 사용하는 것입니다. 그럴 경우 StringIO (또는 cStringIO)에 전달하여 객체와 같은 파일로 만들고 원하는대로 작업을 진행할 수 있습니다. 나는 이것을 테스트하지는 않았지만 대략적으로 보일 것이다 :

def myfunc(x): 
    if isinstance(x, str): 
     x = StringIO.StringIO(x) 
    for line in x: 
     doSomething(line) 
관련 문제