Python3 입력 및 출력


이전 장에서는 실제로 Python의 입력 및 출력 기능에 노출되었습니다. 이번 장에서는 Python의 입력과 출력에 대해 자세히 소개하겠습니다.


출력 형식 미화

Python에는 표현식 문과 print() 함수라는 두 가지 값 출력 방법이 있습니다.

세 번째 방법은 파일 객체의 write() 메서드를 사용하는 것입니다. 표준 출력 파일은 sys.stdout으로 참조할 수 있습니다.


좀 더 다양한 출력을 원할 경우 str.format() 함수를 사용하여 출력 값의 형식을 지정할 수 있습니다.

출력 값을 문자열로 변환하려면 repr() 또는 str() 함수를 사용하면 됩니다.

  • str(): 함수는 사용자가 읽을 수 있는 표현식을 반환합니다.

  • repr(): 통역사가 읽을 수 있는 표현식을 생성합니다.

예를 들어

>>> s = 'Hello, php'
>>> str(s)
'Hello, php'
>>> repr(s)
"'Hello, php'"
>>> str(1/7)
'0.14285714285714285'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'x 的值为: ' + repr(x) + ',  y 的值为:' + repr(y) + '...'
>>> print(s)
x 的值为: 32.5,  y 的值为:40000...
>>> #  repr() 函数可以转义字符串中的特殊字符
... hello = 'hello, php\n'
>>> hellos = repr(hello)
>>> print(hellos)
'hello, php\n'
>>> # repr() 的参数可以是 Python 的任何对象
... repr((x, y, ('Google', 'php')))
"(32.5, 40000, ('Google', 'php'))"

정사각형과 정육면체로 구성된 표를 출력하는 방법에는 두 가지가 있습니다.

>>> for x in range(1, 11):
...     print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
...     # 注意前一行 'end' 的使用
...     print(repr(x*x*x).rjust(4))
...
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000

>>> for x in range(1, 11):
...     print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))
...
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000

참고: 첫 번째 예에서 각 열 사이의 공백은 print()에 의해 추가됩니다.

이 예제에서는 문자열을 오른쪽으로 오프셋하고 왼쪽으로 공백을 채울 수 있는 문자열 개체의 rjust() 메서드를 보여줍니다.

ljust(), center() 등 비슷한 메소드도 있습니다. 이 메서드는 아무 것도 쓰지 않고 새 문자열만 반환합니다.

다음과 같이 왼쪽의 숫자를 0으로 채우는 또 다른 방법 zfill():

>>> '12'.zfill(5)
'00012'
>>> '-3.14'.zfill(7)
'-003.14'
>>> '3.14159265359'.zfill(5)
'3.14159265359'

str.format() 기본 사용법은 다음과 같습니다.

>>> print('{}网址: "{}!"'.format('php中文网', 'www.php.cn'))
php中文网网址: "www.php.cn!"

괄호와 그 안에 있는 문자(라고 함) 형식화 필드)는 format()의 매개변수로 대체됩니다.

괄호 안의 숫자는 아래와 같이 format()에서 들어오는 개체의 위치를 ​​가리키는 데 사용됩니다.

>>> print('{0} 和 {1}'.format('Google', 'php'))
Google 和 php
>>> print('{1} 和 {0}'.format('Google', 'php'))
php 和 Google

format()에서 키워드 인수가 사용되는 경우 해당 값은 다음과 같은 개체를 가리킵니다. 그 이름 매개변수.

>>> print('{name}网址: {site}'.format(name='php中文网', site='www.php.cn'))
php中文网网址: www.php.cn

위치 및 키워드 매개변수는 어떤 방식으로든 결합할 수 있습니다.

>>> print('站点列表 {0}, {1}, 和 {other}。'.format('Google', 'php',
                                                       other='Taobao'))
站点列表 Google, php, 和 Taobao。
'!a'(ascii() 사용), '!s'(str() 사용) 및 '!r'(repr() 사용)은 다음과 같습니다. 사용 형식을 지정하기 전에 값을 변환합니다. :
>>> import math
>>> print('常量 PI 的值近似为: {}。'.format(math.pi))
常量 PI 的值近似为: 3.141592653589793。
>>> print('常量 PI 的值近似为: {!r}。'.format(math.pi))
常量 PI 的值近似为: 3.141592653589793。

선택 사항 ':' 및 형식 식별자는 필드 이름 뒤에 올 수 있습니다. 이를 통해 값의 형식을 더 잘 지정할 수 있습니다. 다음 예에서는 Pi를 소수점 세 자리까지 유지합니다.

>>> import math
>>> print('常量 PI 的值近似为 {0:.3f}。'.format(math.pi))
常量 PI 的值近似为 3.142。

':' 뒤에 정수를 전달하면 필드의 너비가 최소한 이 정도가 됩니다. 테이블을 아름답게 꾸미는 데 유용합니다.

>>> table = {'Google': 1, 'php': 2, 'Taobao': 3}
>>> for name, number in table.items():
...     print('{0:10} ==> {1:10d}'.format(name, number))
...
php     ==>          2
Taobao     ==>          3
Google     ==>          1

포맷 문자열이 길어서 구분하고 싶지 않다면 위치 대신 변수 이름으로 포맷하는 것이 좋을 것 같습니다.

가장 간단한 방법은 사전을 전달한 다음 대괄호 '[]'를 사용하여 키 값에 액세스하는 것입니다.

>>> table = {'Google': 1, 'php': 2, 'Taobao': 3}
>>> print('php: {0[php]:d}; Google: {0[Google]:d}; '
          'Taobao: {0[Taobao]:d}'.format(table))
php: 2; Google: 1; Taobao: 3

테이블 변수 앞에 '**'를 사용하여 동일한 기능을 얻을 수도 있습니다.

>>> table = {'Google': 1, 'php': 2, 'Taobao': 3}
>>> print('php: {php:d}; Google: {Google:d}; Taobao: {Taobao:d}'.format(**table))
php: 2; Google: 1; Taobao: 3

이전 스타일 문자열 형식화

% 연산자도 문자열 형식화를 구현할 수 있습니다. 왼쪽의 매개변수를 sprintf()와 유사한 형식화된 문자열로 사용하고 오른쪽의 매개변수를 대체하여 형식화된 문자열을 반환합니다. 예:

>>> import math
>>> print('常量 PI 的值近似为:%5.3f。' % math.pi)
常量 PI 的值近似为:3.142。

str.format()은 비교적 새로운 함수이기 때문에 대부분의 Python 코드는 여전히 % 연산자를 사용합니다. 하지만 이 구식 형식은 결국 언어에서 제거되므로 str.format()을 더 자주 사용해야 합니다.


키보드 입력 읽기

Python은 표준 입력에서 읽을 수 있도록 input() 설정 기능을 제공합니다. 텍스트의 경우 기본 표준 입력은 키보드입니다.

input은 Python 표현식을 입력으로 받아 연산 결과를 반환할 수 있습니다.

#!/usr/bin/python3

str = input("请输入:");
print ("你输入的内容是: ", str)

입력에 해당하는 다음 결과가 생성됩니다.

请输入:php中文网
你输入的内容是:  php中文网

파일 읽기 및 쓰기

open()은 파일 객체를 반환하며 기본 구문 형식은 다음과 같습니다.

open(filename, mode)
  • 파일 이름: 파일 이름 변수는 액세스하려는 파일의 이름이 포함된 문자열 값입니다.

  • mode: 모드는 파일 열기 모드(읽기 전용, 쓰기, 추가 등)를 결정합니다. 아래에서 가능한 모든 값의 전체 목록을 참조하세요. 이 매개변수는 선택사항이며 기본 파일 액세스 모드는 읽기 전용(r)입니다.

파일을 여는 다양한 모드의 전체 목록:

模式描述
r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
r+打开一个文件用于读写。文件指针将会放在文件的开头。
rb+以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
w+打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb+以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

다음 예에서는 foo.txt 파일에 문자열을 씁니다.

#!/usr/bin/python3

# 打开一个文件
f = open("/tmp/foo.txt", "w")

f.write( "Python 是一个非常好的语言。\n是的,的确非常好!!\n" )

# 关闭打开的文件
f.close()
  • 첫 번째 매개변수는 열려는 파일의 이름입니다.

  • 두 번째 매개변수는 파일이 문자를 사용하는 방식을 설명합니다. mode는 파일이 읽기 전용인 경우 'r', 쓰기 전용인 경우 'w'(동일한 이름의 파일이 있는 경우 삭제됨), 기록된 모든 데이터를 추가하는 경우 'a'가 될 수 있습니다. 끝에 자동으로 추가됩니다. 'r+'는 읽기와 쓰기 모두에 사용됩니다. 모드 매개변수는 선택사항입니다. 기본값은 'r'입니다.

이때 foo.txt 파일을 열면 다음과 같이 표시됩니다.

$ cat /tmp/foo.txt 
Python 是一个非常好的语言。
是的,的确非常好!!

파일 객체의 메소드

이 섹션의 나머지 예제에서는 f라는 파일 객체가 생성되었다고 가정합니다.

f.read()

파일의 내용을 읽으려면 f.read(size)를 호출하세요. f.read(size)는 특정 양의 데이터를 읽고 이를 문자열이나 바이트열 객체로 반환합니다.

size는 선택적인 숫자 매개변수입니다. size가 생략되거나 음수이면 파일의 전체 내용을 읽고 반환합니다.

다음 예에서는 foo.txt 파일이 이미 존재한다고 가정합니다(위 예에서 생성됨).

#!/usr/bin/python3

# 打开一个文件
f = open("/tmp/foo.txt", "r")

str = f.read()
print(str)

# 关闭打开的文件
f.close()

위 프로그램을 실행하면 출력 결과는 다음과 같습니다.

Python 是一个非常好的语言。
是的,的确非常好!!

f.readline()

f.readline() 파일에서 읽습니다. 별도의 줄을 사용합니다. 개행 문자는 'n'입니다. f.readline()이 빈 문자열을 반환하면 마지막 줄을 읽었다는 의미입니다.

#!/usr/bin/python3

# 打开一个文件
f = open("/tmp/foo.txt", "r")

str = f.readline()
print(str)

# 关闭打开的文件
f.close()

위 프로그램을 실행하면 출력 결과는 다음과 같습니다.

Python 是一个非常好的语言。

f.readlines()

f.readlines()는 파일에 포함된 모든 줄을 반환합니다.

선택적 매개변수 sizehint가 설정된 경우 지정된 길이의 바이트를 읽어 행으로 나눕니다.

#!/usr/bin/python3

# 打开一个文件
f = open("/tmp/foo.txt", "r")

str = f.readlines()
print(str)

# 关闭打开的文件
f.close()

위 프로그램을 실행하면 출력 결과는 다음과 같습니다.

['Python 是一个非常好的语言。\n', '是的,的确非常好!!\n']

또 다른 방법은 파일 개체를 반복하고 각 줄을 읽는 것입니다.

#!/usr/bin/python3

# 打开一个文件
f = open("/tmp/foo.txt", "r")

for line in f:
    print(line, end='')

# 关闭打开的文件
f.close()

위 프로그램을 실행하면 출력 결과는 다음과 같습니다.

Python 是一个非常好的语言。
是的,的确非常好!!

이 방법은 매우 간단합니다. , 그러나 그렇지 않습니다. 좋은 제어 기능을 제공하지 않습니다. 두 가지 처리 메커니즘이 다르기 때문에 혼합하지 않는 것이 가장 좋습니다.

f.write()

f.write(string)는 파일에 문자열을 쓰고 쓴 문자 수를 반환합니다.

#!/usr/bin/python3

# 打开一个文件
f = open("/tmp/foo.txt", "w")

num = f.write( "Python 是一个非常好的语言。\n是的,的确非常好!!\n" )
print(num)
# 关闭打开的文件
f.close()

위 프로그램을 실행하면 출력 결과는 다음과 같습니다.

29

문자열이 아닌 것을 작성하려면 먼저 문자열을 변환해야 합니다.

#!/usr/bin/python3

# 打开一个文件
f = open("/tmp/foo1.txt", "w")

value = ('www.php.cn', 14)
s = str(value)
f.write(s)

# 关闭打开的文件
f.close()

위 프로그램을 실행하고 foo1.txt 파일을 엽니다. :

$ cat /tmp/foo1.txt 
('www.php.cn', 14)

f.tell()

f.tell()은 파일 시작 부분부터의 바이트 수인 파일 객체의 현재 위치를 반환합니다.

f.seek()

파일의 현재 위치를 변경하려면 f.seek(offset, from_what) 함수를 사용하면 됩니다.

from_what의 값은 0이면 시작을 의미하고, 1이면 현재 위치를 의미하며, 2는 파일의 끝을 의미합니다. 예:


  • seek(x ,0): 파일의 첫 번째 줄인 시작 위치부터 문자가 x자를 이동하기 시작합니다.

  • seek(x,1): 현재 위치에서 x자를 뒤로 이동하는 것을 의미합니다.

  • seek(- x,2): 파일 끝에서 x 문자 앞으로 이동하는 것을 의미합니다.

from_what 값의 기본값은 파일의 시작 부분인 0입니다. 전체 예는 다음과 같습니다.

>>> f = open('/tmp/foo.txt', 'rb+')
>>> f.write(b'0123456789abcdef')
16
>>> f.seek(5)     # 移动到文件的第六个字节
5
>>> f.read(1)
b'5'
>>> f.seek(-3, 2) # 移动到文件的倒数第三字节
13
>>> f.read(1)
b'd'


f.close()

텍스트 파일(파일 열기 모드에서 b가 없는 파일)에서는 파일의 시작 위치를 기준으로만 위치가 지정됩니다.


파일 처리가 끝나면 f.close()를 호출하여 파일을 닫고 시스템 리소스를 해제합니다. 파일을 다시 호출하려고 하면 예외가 발생합니다.

>>> f.close()
>>> f.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: I/O operation on closed file
<pre>
<p>
当处理一个文件对象时, 使用 with 关键字是非常好的方式。在结束后, 它会帮你正确的关闭文件。 而且写起来也比 try - finally 语句块要简短:</p>
<pre>
>>> with open('/tmp/foo.txt', 'r') as f:
...     read_data = f.read()
>>> f.closed
True

파일 객체에는 isatty() 및 trucate()와 같은 다른 메서드가 있지만 일반적으로 덜 사용됩니다.


pickle 모듈

Python의 pickle 모듈은 기본 데이터 시퀀스와 역직렬화를 구현합니다.

피클 모듈의 직렬화 연산을 통해 프로그램에서 실행 중인 객체 정보를 파일로 저장하여 영구적으로 보관할 수 있습니다.

피클 모듈의 역직렬화 작업을 통해 파일에서 마지막 프로그램이 저장한 객체를 생성할 수 있습니다.

기본 인터페이스:

pickle.dump(obj, file, [,protocol])

pickle 개체를 사용하면 읽기 위해 파일을 열 수 있습니다.

x = pickle.load(file)

참고: 파일에서 문자열을 읽고 이를 원래 Python 개체로 재구성합니다.

file: read() 및 readline() 인터페이스가 있는 파일과 유사한 객체입니다.

인스턴스 1:

#!/usr/bin/python3
import pickle

# 使用pickle模块将数据对象保存到文件
data1 = {'a': [1, 2.0, 3, 4+6j],
         'b': ('string', u'Unicode string'),
         'c': None}

selfref_list = [1, 2, 3]
selfref_list.append(selfref_list)

output = open('data.pkl', 'wb')

# Pickle dictionary using protocol 0.
pickle.dump(data1, output)

# Pickle the list using the highest protocol available.
pickle.dump(selfref_list, output, -1)

output.close()

인스턴스 2:

#!/usr/bin/python3
import pprint, pickle

#使用pickle模块从文件中重构python对象
pkl_file = open('data.pkl', 'rb')

data1 = pickle.load(pkl_file)
pprint.pprint(data1)

data2 = pickle.load(pkl_file)
pprint.pprint(data2)

pkl_file.close()