python输入输出代码_python输入输出

本文记录一些与python输入输出有关的事情。主要分为以下几个部分标准输入

标准输出

用print输出进度条

StringIO

标准输入

总结一下sys.stdin的几种用法。

注:下面这些代码的功能类似input,代码写在py文件里,用cmd调用运行时,需要输入一些字符串,如果输入多行字符串要用Ctrl+D(Unix)或Ctrl+Z(Windows)停止输入,然后字符串的内容就会赋值给变量a,程序再对a进行后续处理。

1.输入多行,a是一个多行字符串

import sys

a = sys.stdin.read()

print(a)

2.输入多行,a是一个列表,列表中每一个元素对应字符串的一行,行末的\n也还在

import sys

a = sys.stdin.readlines()

print(a)

可以这样用

import sys

for line in sys.stdin.readlines():

print(line.strip())

3.输入单行,a直接就是那一行字符串

import sys

a = sys.stdin.readline()

print(a)

4.每调用一次next要多输入一行

import sys

f = sys.stdin

a = next(f)

b = next(f)

print(a, b)

循环则需要不停输入

import sys

for line in sys.stdin:

print(line)

用readline可以达到相同效果

import sys

while True:

try:

line = sys.stdin.readline()

except KeyboardInterrupt:

break

if not line:

break

print(line)

注意以下几点上面这些无法在jupyter中尝试,要写入文件,运行这个文件,python main.py

每一行都是raw格式的,即输入ab\nc时得到的字符串是r'ab\nc',实际上是'ab\\nc',因此print出来后\n还在;而输入多行时回车则不一样,比如输入ab\nc回车,得到的是'ab\\nc\n'

sys.stdin与可读文件对象具有相同的类型,如下所示,因此才都可以调用read,readlines等方法。只是stdin默认从运行py文件的窗口中读取字符,而open(file, 'r')则从file文件中读取字符。

import sys

print(sys.stdin)

with open('test.txt', 'r') as f:

print(f)

# 输出结果

<_io.TextIOWrapper name='' mode='r' encoding='cp936'>

<_io.TextIOWrapper name='test.txt' mode='r' encoding='cp936'>

我们也可以写着标准输入的代码,实际上却将文件内容传进来,比如两个文件分别像下面这样编辑(放在相同目录下)

# main.py

import sys

for line in sys.stdin.readlines():

print(line.strip())

# test.txt

abc

bcd

efg

(linux下)运行python main.py < test.txt,则会将test.txt文件中的内容输出。这样做和直接运行下面的代码是一样的

with open('test.txt', 'r') as f:

for line in f.readlines():

print(line.strip())

另外,python3中input可以接受一行的输入,与readline的区别在于input可以给出一段提示,而且input会把最后的\n去掉

a = input('please input one line:')

print(a)

标准输出

sys.stdout与可写文件对象具有相同的类型,如open(file, 'w')这个对象,它们都可以通过write方法将字符串输出到目标位置open(file, 'w').write()将字符串写入file文件,

stdout.write()将字符串写到运行py文件的窗口,功能和我们熟悉的print相同。而实际上print正是调用stdout.write()实现的。print是stdout.write的扩展,比如后者只能接受字符串,而前者可以接受很多类型;还有print默认最后加一个\n、可以接受多个参数等等。

因此当我们看到这样的代码,看成print就好了

import sys

sys.stdout.write('abc')

有时我们会看到这种形式

import sys

sys.stdout.write('abc')

sys.stdout.flush()

flush只是为了实时显示输出(将原来写到缓存区中的内容显示出来),比如下面这段代码,不加flush时5个数字会在最后一起输出,而用flush则会一个一个显示出来

import sys

import time

for i in range(5):

sys.stdout.write(str(i))

# sys.stdout.flush()

time.sleep(0.5)

其实最后加一个\n不需要flush也会实时输出

import sys

import time

for i in range(5):

sys.stdout.write('{}\n'.format(i))

time.sleep(0.5)

我们一般用print都会实时输出,因为它默认最后输出一个\n,如果最后去掉\n,则也不会实时输出,如下所示

import time

import sys

for i in range(5):

print(i, end='')

# sys.stdout.flush()

time.sleep(0.5)

我们可以加上flush那一行使其实时输出,也可以改flush参数print(i, end='', flush=True)。

前面提到,print()是在调用sys.stdout.write(),那么如果将sys.stdout换成文件(反正类型是相同的),是不是print就可以输出到文件了呢?确实如此。试一试下面一段代码

import sys

sys.stdout = open('test.txt', 'w')

print('first line')

print('second line')

运行后test.txt文件就变成了

first line

second line

其实这也可以用print的参数来完成

with open('test.txt', 'w') as f:

print('first line', file=f)

print('second line', file=f)

回过头来发现,我们把print的参数玩了一个遍

print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

此外,与输入相同,输出时也可以用print不加改动,将输出重定向到文件中

print('first line')

print('second line')

上面代码在linux下用python main.py >> test.txt运行,即可将print写入test.txt文件中。

显示进度

我们这里不用python中的一些库来实现进度条,而是用print来完成。使用\r每次将光标移动到行首,如下所示

import time

n = 142

for i in range(n):

print('\r{}/{}'.format(i+1, n), end='')

time.sleep(0.05)

用print('{} / {}'.format(i+1, n), end='\r')一般也可以。

但有时基数太大,比如1545643/55969685,很难很快看出进行到哪了,这时需要看百分比

import time

n = 142

for i in range(n):

print('\r{0:.0%}'.format((i+1)/n), end='')

time.sleep(0.05)

也可以既显示实际数量,又显示进度条

import time

n = 206

for i in range(n):

m = int((i+1) / n * 60)

progressbar = '\r{}/{}, |{}>{}|'.format(i+1, n, '='*m, '-'*(60-m))

print(progressbar, end='')

time.sleep(0.05)

显示结果如下

116 / 206, |=================================>---------------------------|

上面如果运行很大基数的情况,可能会出问题,看下面这个例子,为了更快出结果,我将time.sleep省掉了

n = 5000

for i in range(n):

count = i + 1

print('{}/{}'.format(count, n), end='\r')

输出结果没有全都在一行,而是这样的,n越大会积累越多行。

2550 / 5000

4672 / 5000

5000 / 5000

这个问题应该跟flush有关,调用\r虽然也会实时显示,但缓存区中的东西貌似没有清理,积累到一定程度就会输出个\n来flush,如果我们加一个flush=True就可以解决这个问题

n = 5000

for i in range(n):

count = i + 1

print('{}/{}'.format(count, n), end='\r', flush=True)

但这样做屏幕就会极频繁地刷新,本来早该结束的程序却因为没有输出完而没有停止,后面程序运行的结果也没法输出。所以可以少输出一些

n = 5000

for i in range(n):

count = i + 1

if count % 50 == 0:

print('{}/{}'.format(count, n), end='\r', flush=True)

StringIO

在内存中读写字符串。想象一个场景:一个函数需要输入的参数是文件对象,但我们现在手上只有字符串,如果想传入这个函数中,就要先读入一个文件,再读出来传入,然后还要把文件删掉,这就非常麻烦。StringIO可以让我们直接从内存中读取字符串形成一个文件对象

from io import StringIO

f = StringIO('Hello World!')

f.read()

f也可以调用write继续写入。StringIO只能读取字符串,如果是二进制数据,要用BytesIO。

注意事项想打空行用print(),不要用print('\n'),因为后者会打两个空行,相当于print('\n', end='\n')

更多遇到了再补充…

专栏信息

专栏目录:目录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值