open with 문을 사용하여 파일을 여는 방법


201

파이썬에서 파일 입력 및 출력을 수행하는 방법을 찾고 있습니다. 파일의 이름과 이름을 확인하고 파일의 발생에 텍스트를 추가하면서 파일에서 다른 파일로 이름 목록 (한 줄에 하나씩)을 읽는 다음 코드를 작성했습니다. 코드가 작동합니다. 더 잘할 수 있을까?

with open(...입력 및 출력 파일 모두에 명령문 을 사용하고 싶었지만 동일한 블록에 어떻게 존재할 수 있는지 알 수 없으므로 임시 위치에 이름을 저장해야합니다.

def filter(txt, oldfile, newfile):
    '''\
    Read a list of names from a file line by line into an output file.
    If a line begins with a particular name, insert a string of text
    after the name before appending the line to the output file.
    '''

    outfile = open(newfile, 'w')
    with open(oldfile, 'r', encoding='utf-8') as infile:
        for line in infile:
            if line.startswith(txt):
                line = line[0:len(txt)] + ' - Truly a great person!\n'
            outfile.write(line)

    outfile.close()
    return # Do I gain anything by including this?

# input the name you want to check against
text = input('Please enter the name of a great person: ')    
letsgo = filter(text,'Spanish', 'Spanish2')

"이름을 임시 위치에 저장해야한다는 것을 의미합니까?" 이것의 의미를 설명 할 수 있습니까?
S.Lott

4
참고 filter()되는 내장 함수 당신은 아마 당신의 기능에 대한 다른 이름을 선택해야하므로.
Tom

2
@Tom은 네임 스페이스의 함수가 내장 함수보다 우선합니까?
UpTide

2
@UpTide : 예. Python은 로컬, 엔 클로징, 글로벌, 내장 LEGB 순서로 작동합니다 ( stackoverflow.com/questions/291978/… 참조 ). 따라서 전역 함수 ( filter()) 를 만들면 내장 함수 전에 찾을 수 있습니다.filter()
Tom

답변:


309

파이썬은 open()하나의 문장에 여러 문장을 넣을 수 있습니다 with. 쉼표로 구분하십시오. 그러면 코드는 다음과 같습니다.

def filter(txt, oldfile, newfile):
    '''\
    Read a list of names from a file line by line into an output file.
    If a line begins with a particular name, insert a string of text
    after the name before appending the line to the output file.
    '''

    with open(newfile, 'w') as outfile, open(oldfile, 'r', encoding='utf-8') as infile:
        for line in infile:
            if line.startswith(txt):
                line = line[0:len(txt)] + ' - Truly a great person!\n'
            outfile.write(line)

# input the name you want to check against
text = input('Please enter the name of a great person: ')    
letsgo = filter(text,'Spanish', 'Spanish2')

그리고 아닙니다 return. 함수의 끝에 명시 적으로 넣음으로써 아무것도 얻지 못합니다 . return일찍 종료 하는 데 사용할 수 있지만 마지막에 종료하면 함수가 종료되지 않습니다. (물론 값을 반환하는 함수에서는를 사용하여 반환 할 값 return을 지정합니다.)

명령문이 도입 될 때 Python 2.5 에서 또는 Python 2.6에서 여러 open()항목을 사용하는 with것은 지원되지 with않았지만 Python 2.7 및 Python 3.1 이상에서는 지원됩니다.

http://docs.python.org/reference/compound_stmts.html#the-with-statement http://docs.python.org/release/3.1/reference/compound_stmts.html#the-with-statement

Python 2.5, 2.6 또는 3.0에서 실행해야하는 코드를 작성하는 with경우 다른 답변에서 제안하거나 사용하는대로 명령문을 중첩하십시오 contextlib.nested.


29

이렇게 중첩 된 블록을 사용하십시오.

with open(newfile, 'w') as outfile:
    with open(oldfile, 'r', encoding='utf-8') as infile:
        # your logic goes right here

12

블록으로 중첩 할 수 있습니다. 이처럼 :

with open(newfile, 'w') as outfile:
    with open(oldfile, 'r', encoding='utf-8') as infile:
        for line in infile:
            if line.startswith(txt):
                line = line[0:len(txt)] + ' - Truly a great person!\n'
            outfile.write(line)

outfile코드에 예외가 발생하더라도 닫히 도록 보장하기 때문에 버전보다 낫습니다 . 분명히 당신은 try / finally로 그렇게 할 수 있지만 with이것을하는 올바른 방법입니다.

또는 방금 배운 것처럼 @steveha에서 설명한 것처럼 with 문에 여러 컨텍스트 관리자를 가질 수 있습니다 . 그것은 중첩보다 더 나은 옵션 인 것 같습니다.

그리고 당신의 마지막 사소한 질문에 대해, 수익은 실제적인 목적을 제공하지 않습니다. 나는 그것을 제거 할 것입니다.


매우 감사합니다. 나는 그것을 시도하고 작동 할 때 당신의 대답을 받아 들일 것입니다.
Disnami

다시 감사합니다. 수락하기 전에 7 분 동안 기다려야합니다.
Disnami

7
@Disnami 메이크업은 반드시 정답을 받아 (그리고이 일이 아니에요!) ;-)
데이비드 헤퍼에게

1

때로는 다양한 양의 파일을 열고 각 파일을 동일하게 취급하고 싶을 수도 있습니다. contextlib

from contextlib import ExitStack
filenames = [file1.txt, file2.txt, file3.txt]

with open('outfile.txt', 'a') as outfile:
    with ExitStack() as stack:
        file_pointers = [stack.enter_context(open(file, 'r')) for file in filenames]                
            for fp in file_pointers:
                outfile.write(fp.read())                   
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.