복붙노트

[PYTHON] 파이썬에서 EOF까지 반복하는 법?

PYTHON

파이썬에서 EOF까지 반복하는 법?

나는 파일과 같은 객체의 끝을 찾을 때까지 반복 할 필요가 있지만, "명백한 방법"을 찾지는 못하기 때문에 나는 뭔가를 간과하고있는 것 같아 보인다. :-)

나는 스트림을 가지고 있는데 (이 경우에는 StringIO 객체이지만, " "형식으로 알 수없는 레코드 수를 저장하는 일반 사건에 대해서도 궁금하다.

data = StringIO("\x07\x00\x00\x00foobar\x00\x04\x00\x00\x00baz\x00")

자, 내가 이것을 읽을 수있는 유일한 명확한 방법은 (내가 생각하는 것처럼) 초기화되지 않은 루프를 사용하는 것입니다.

len_name = data.read(4)

while len_name != "":
    len_name = struct.unpack("<I", len_name)[0]
    names.append(data.read(len_name))

    len_name = data.read(4)

C와 비슷한 언어에서, 나는 while의 test 절에서 read (4)를 사용 하겠지만, 물론 Python에서는 작동하지 않을 것이다. 이것을 달성하기위한 더 좋은 방법에 대한 생각?

해결법

  1. ==============================

    1.iter ()를 통해 반복을 sentinel과 결합 할 수 있습니다.

    iter ()를 통해 반복을 sentinel과 결합 할 수 있습니다.

    for block in iter(lambda: file_obj.read(4), ""):
      use(block)
    
  2. ==============================

    2.텍스트 파일의 행을 반복하는 방법을 보았습니까?

    텍스트 파일의 행을 반복하는 방법을 보았습니까?

    for line in file_obj:
      use(line)
    

    자신 만의 발전기로도 같은 일을 할 수 있습니다 :

    def read_blocks(file_obj, size):
      while True:
        data = file_obj.read(size)
        if not data:
          break
        yield data
    
    for block in read_blocks(file_obj, 4):
      use(block)
    

    참조 :

  3. ==============================

    3.이것을 for-loop로 바꾸기 위해 이미 언급 된 iterator 기반 솔루션을 선호합니다. 직접 작성된 또 다른 해결책은 Knuth의 "루프 앤 하프"

    이것을 for-loop로 바꾸기 위해 이미 언급 된 iterator 기반 솔루션을 선호합니다. 직접 작성된 또 다른 해결책은 Knuth의 "루프 앤 하프"

    while 1:
        len_name = data.read(4)
        if not len_name:
            break
        names.append(data.read(len_name))
    

    비교를 통해 쉽게 자체 발전기로 끌어 올려 for-loop로 사용되는 것을 볼 수 있습니다.

  4. ==============================

    4.예상대로, 일반적으로 가장 많이 사용되는 대답은 "한 번에 4 바이트 씩"특수화 된 발전기를 사용하는 것입니다. 때로는 일반성이 그다지 열심히 (그리고 훨씬 더 보람 ;-)하지 않으므로, 대신 다음과 같은 매우 일반적인 해결책을 제안했습니다.

    예상대로, 일반적으로 가장 많이 사용되는 대답은 "한 번에 4 바이트 씩"특수화 된 발전기를 사용하는 것입니다. 때로는 일반성이 그다지 열심히 (그리고 훨씬 더 보람 ;-)하지 않으므로, 대신 다음과 같은 매우 일반적인 해결책을 제안했습니다.

    import operator
    def funlooper(afun, *a, **k):
      wearedone = k.pop('wearedone', operator.not_)
      while True:
        data = afun(*a, **k)
        if wearedone(data): break
        yield data
    

    이제 원하는 루프 헤더는 funlooper (data.read, 4)의 len_name에 대한 것입니다.

    편집 : 모든 것의 "숨겨진 의존성"을 갖는 것에 대한 약간 덜 일반적인 이전 버전 (데이터가 아닌 것처럼 종료 테스트를 하드 코딩)으로 비난 한 의견이 wearedone 관용구로 훨씬 더 일반화되었습니다. -)

    루핑하는 일반적인 스위스 군용 칼 인 itertools도 평소와 같이 훌륭합니다.

    import itertools as it
    
    for len_name in it.takewhile(bool, it.imap(data.read, it.repeat(4))): ...
    

    또는 매우 동등하게 :

    import itertools as it
    
    def loop(pred, fun, *args):
      return it.takewhile(pred, it.starmap(fun, it.repeat(args)))
    
    for len_name in loop(bool, data.read, 4): ...
    
  5. ==============================

    5.파이썬의 EOF 마커는 빈 문자열이므로,이 함수를 반복자에서 감싸는 함수를 작성하지 않고 얻을 수있는 최선의 결과에 매우 가깝습니다. while을 다음과 같이 변경하여 좀 더 파이썬적인 방법으로 작성할 수 있습니다.

    파이썬의 EOF 마커는 빈 문자열이므로,이 함수를 반복자에서 감싸는 함수를 작성하지 않고 얻을 수있는 최선의 결과에 매우 가깝습니다. while을 다음과 같이 변경하여 좀 더 파이썬적인 방법으로 작성할 수 있습니다.

    while len_name:
        len_name = struct.unpack("<I", len_name)[0]
        names.append(data.read(len_name))
        len_name = data.read(4)
    
  6. ==============================

    6.나는 가독성을 위해 Tendayi의 제안 함수 및 반복자와 함께 갈 것입니다.

    나는 가독성을 위해 Tendayi의 제안 함수 및 반복자와 함께 갈 것입니다.

    def read4():
        len_name = data.read(4)
        if len_name:
            len_name = struct.unpack("<I", len_name)[0]
            return data.read(len_name)
        else:
            raise StopIteration
    
    for d in iter(read4, ''):
        names.append(d)
    
  7. from https://stackoverflow.com/questions/1752107/how-to-loop-until-eof-in-python by cc-by-sa and MIT license