6.1 输入和输出概述
程序通过输入接收待处理的数据,然后执行相应的处理,最后通过输出返回处理的结果
python通常可以使用下列方式之一实现交互功能
- 命令行参数
- 标准输入和输出函数
- 文件输入和输出
- 图形化用户界面
6.2 命令行参数
6.2.1 sys.argv与命令行参数
在Python程序中,sys.argv是一个命令行参数的列表。在执行Python脚本时,可以通过命令行输入参数,这些参数会按顺序依次保存在sys.argv列表中。通常,sys.argv的第一个元素是脚本本身的名称,从第二个元素开始才是实际的命令行参数。
下面是一个简单的例子,演示如何在Python程序中使用sys.argv获取命令行参数:
import sys
#打印脚本名称和传入的参数
print("脚本名称:", sys.argv[0])
print("参数列表:", sys.argv[1:])
假设上述脚本保存为test.py,接下来在命令行执行以下命令:
$ python test.py arg1 arg2 arg3
输出如下所示:
脚本名称: test.py
参数列表: ['arg1', 'arg2', 'arg3']
在上述例子中,sys.argv列表的第一个元素是test.py脚本本身的名称,而从第二个元素开始才是实际的命令行参数。
通过sys.argv解析命令行参数可以方便地控制程序的行为。例如,在开发命令行工具时,可以根据传入的参数决定程序执行的行为,或者读取配置文件或数据文件等。
6.2.2 argparse模块和命令行参数解析
argparse
是Python中用于解析命令行参数的一个标准库。使用argparse
模块可以轻松地编写用户友好的命令行界面,定义程序接受的选项和参数,并自动生成帮助和使用消息。
下面是一个简单的例子,演示如何使用argparse
模块解析命令行参数:
import argparse
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
const=sum, default=max,
help='sum the integers (default: find the max)')
args = parser.parse_args()
print(args.accumulate(args.integers))
在这个例子中,我们创建了一个ArgumentParser
对象,指定了程序的描述信息和一个integers
参数,该参数接受一个或多个整数。我们还添加了一个--sum
选项,该选项将accumulate
属性设置为sum
,以执行整数求和操作。如果没有提供--sum
选项,则默认使用max
函数求出整数中的最大值。
要运行这个程序,可以在命令行中提供一些整数,例如:
$ python argparse_example.py 1 2 3 4
这将输出整数的最大值,即4
。要计算这些整数的总和,可以使用--sum
选项:
$ python argparse_example.py 1 2 3 4 --sum
这将输出整数的总和,即10
。
argparse
模块还支持许多其他功能,例如:
- 添加布尔选项
- 添加互斥选项
- 指定参数的数据类型
- 添加默认值
- 指定参数的帮助信息
- 分组参数等
通过使用这些功能,可以创建具有复杂参数解析需求的命令行工具。
6.3 标准输入和标准输出函数
在Python中,标准输入和标准输出可以使用sys.stdin
和sys.stdout
访问。sys.stdin
是一个类文件对象,可以从其中读取输入,而sys.stdout
是一个类文件对象,可以将输出写入其中。这些文件对象的默认值通常是标准输入和标准输出,但可以通过重定向来更改。
下面是一个简单的例子,演示如何使用标准输入和标准输出:
import sys
# 从标准输入读取一行
line = sys.stdin.readline()
# 将读取的行写入标准输出
sys.stdout.write(line)
在这个例子中,我们从标准输入中读取一行,并将该行写入标准输出。要运行此程序,可以在命令行中输入一行文本,例如:
$ python stdin_stdout_example.py
hello world
这将将hello world
写入标准输出。请注意,在这个例子中,我们没有使用print
函数,而是直接使用了sys.stdout.write
函数来将文本写入标准输出。
除了sys.stdin
和sys.stdout
,Python还提供了input
和print
函数,可以更方便地读取输入和输出。input
函数从标准输入读取一行文本,并将其作为字符串返回,而print
函数将一个或多个值打印到标准输出,以空格分隔。
下面是一个使用input
和print
函数的例子:
# 从标准输入读取一行
line = input()
# 将读取的行打印到标准输出
print(line)
这个例子与前面的例子相同,但使用了input
和print
函数。运行这个程序的方式与前面的示例相同。
import datetime
sName = input("请输入您的姓名:")
birthday = int(input("请输入您的出生年份:"))
age = datetime.date.today().year - birthday
print("您好!{0},您{1}岁。".format(sName,age))
6.3.2 交互式用户输入
#交互式用户输入
a = []
x = float(input("please give a number,-1 = stop:"))
while x != -1:
a.append(x)
x = float(input("please give a number,-1 = stop:"))
print("count:",len(a))
print("sum:",sum(a))
print("average",sum(a)/len(a))
6.3.3 运行时提示输入密码
getpass
是Python标准库中的一个模块,用于从终端获取密码而不在屏幕上显示密码。这是一种安全的方法,可以避免密码被他人看到。
getpass
模块提供了一个函数getpass
,该函数提示用户输入密码,并返回输入的密码作为字符串,而不在屏幕上显示密码。以下是getpass
函数的语法:
import getpass
password = getpass.getpass(prompt='Enter password: ')
getpass
函数的prompt
参数用于指定用户应输入的信息。默认情况下,该参数为'Password: '
。
以下是一个使用getpass
模块的示例:
import getpass
username = input("Enter your username: ")
password = getpass.getpass(prompt='Enter your password: ')
print("Username:", username)
print("Password:", password)
在这个例子中,我们使用input
函数提示用户输入他们的用户名,并使用getpass
函数提示用户输入密码。然后,我们使用print
函数打印用户名和密码。在屏幕上,密码不会显示为明文,而是显示为空字符串。
当用户输入密码时,getpass
函数将输入的密码作为字符串返回。这个密码可以安全地用于进行身份验证或其他需要密码的操作。
6.4 文件和文件对象
6.4.1文件对象和open()函数
open()
是Python中用于打开文件的内置函数。它接受一个文件名作为参数,并返回一个文件对象,可以用于读取或写入文件。以下是open()
函数的基本语法:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
其中,file
参数是要打开的文件名,可以是绝对路径或相对路径。mode
参数是一个字符串,用于指定文件的打开模式,可以是'r'
(读取模式,默认值),'w'
(写入模式),'a'
(附加模式),'x'
(独占创建模式),'b'
(二进制模式),'t'
(文本模式,默认值),'+'
(读写模式)等。buffering
表示是否使用缓存(默认为-1,表示使用系统默认的缓冲区大小);encoding是文件的编码。
文件操作容易发生异常,而且最后需要关闭打开的文件,故一般使用try…except…finally语句,在try与语句块中执行文件的相关操作,使用except捕获可能发生的异常,在finally语句块中确保关闭打开的文件。
try:
f = open(file,mode)
#操作打开的文件
except:
#发生异常时执行的操作
finally:
f.close()
以下是一个使用open()
函数打开文件并读取文件内容的示例:
# 打开文件并读取文件内容
with open('example.txt', 'r') as file:
content = file.read()
# 打印文件内容
print(content)
在这个例子中,我们使用open()
函数打开名为example.txt
的文件,并将文件对象存储在file
变量中。然后,我们使用read()
方法读取文件内容,并将其存储在content
变量中。
需要注意的是,open()
函数返回的文件对象必须使用with
语句或手动调用close()
方法进行关闭。使用with
语句可以确保文件对象在使用后被自动关闭,从而避免资源泄漏。
以下是一个使用open()
函数写入文件的示例:
# 打开文件并写入内容
with open('example.txt', 'w') as file:
file.write('Hello, world!')
# 打开文件并附加内容
with open('example.txt', 'a') as file:
file.write(' Goodbye, world!')
# 打开文件并读取内容
with open('example.txt', 'r') as file:
content = file.read()
# 打印文件内容
print(content)
在这个例子中,我们首先使用open()
函数以写入模式打开文件,并使用write()
方法向文件中写入一些文本。然后,我们再次使用open()
函数以附加模式打开文件,并使用write()
方法向文件中添加更多文本。最后,我们再次使用open()
函数以读取模式打开文件,并使用read()
方法读取文件内容。
6.4.2 文件的打开,写入,读取和关闭
import sys
filename = sys.argv[0] #所读取并输出的就是本程序文件type_file.py
f=open(filename, 'r', encoding='utf8') #打开文件
line_no=0 #统计行号
while True:
line_no += 1 #行号计数
line = f.readline() #读取行信息
if line:
print(line_no, ":", line) #输出行号和该行内容
else:
break
f.close() #关闭打开的文件
6.4.3 with语句和上下文管理协议
with
语句是Python中一种用于处理资源管理的语法结构。它的主要作用是自动获取和释放资源,例如打开文件、建立数据库连接等。
with
语句的基本语法如下:
with resource as variable:
# 使用变量操作资源
其中,resource
是要获取的资源,可以是一个文件对象、一个数据库连接等,而variable
是资源对象的别名,可以在with
语句的代码块中使用。
与传统的资源管理方式不同,使用with
语句可以确保资源在使用完毕后自动释放。这样可以避免资源泄漏和程序错误,提高程序的可维护性和可读性。
以下是一个使用with
语句读取文件内容的示例:
# 打开文件并读取文件内容
with open('example.txt', 'r') as file:
content = file.read()
# 打印文件内容
print(content)
在这个例子中,我们使用with
语句打开名为example.txt
的文件,并将文件对象存储在file
变量中。在with
语句的代码块中,我们使用read()
方法读取文件内容,并将其存储在content
变量中。
需要注意的是,使用with
语句打开文件时,如果文件不存在,将会引发FileNotFoundError
异常。如果文件无法读取或写入,将会引发IOError
异常。在使用with
语句时,不需要显式地调用close()
方法,因为在代码块结束时,资源会自动释放。
import sys
filename = sys.argv[0] #所读取并输出的就是本程序文件type_file.py
line_no = 0 #统计行号
with open(filename, 'r', encoding='utf8') as f:
for line in f:
line_no += 1
print(line_no,":",line)
f.close() #关闭打开的文件
除了文件对象,with
语句还可以用于其他类型的资源管理,例如数据库连接、网络连接等。在这些情况下,使用with
语句可以确保资源在使用完毕后自动关闭和回收。
6.5 标准输入,输出和错误流文件对象
6.5.1 标准输入,输出和错误流文件对象
在操作系统中,程序的输入、输出和错误信息通常被称为标准输入、标准输出和标准错误。在Python中,可以使用文件对象来访问这些标准流。
标准输入(stdin)是程序接受输入的主要方式,通常是从键盘读取输入。在Python中,sys.stdin
是一个文件对象,可以使用read()
方法从中读取输入。以下是一个简单的使用标准输入的示例:
import sys
# 从标准输入读取一行
line = sys.stdin.readline()
# 打印读取的行
print(line)
这个例子中,我们使用sys.stdin
读取标准输入中的一行,并使用print()
函数打印读取的行。在命令行中,可以将输入重定向到文件或管道中,例如:
$ python input_example.py < input.txt
这将从名为input.txt
的文件中读取输入,并将其传递给Python程序作为标准输入。
标准输出(stdout)是程序输出信息的主要方式,通常是将信息打印到屏幕上。在Python中,sys.stdout
是一个文件对象,可以使用write()
方法将信息输出到标准输出。以下是一个简单的使用标准输出的示例:
import sys
# 将一行文本写入标准输出
sys.stdout.write("Hello, world!")
这个例子中,我们使用sys.stdout.write()
将一行文本写入标准输出。在命令行中,可以将输出重定向到文件或管道中,例如:
$ python output_example.py > output.txt
这将将输出重定向到名为output.txt
的文件中。
标准错误(stderr)通常用于输出错误信息或调试信息,通常也是将信息打印到屏幕上。在Python中,sys.stderr
是一个文件对象,可以使用write()
方法将错误信息输出到标准错误。以下是一个简单的使用标准错误的示例:
import sys
# 将一行错误信息写入标准错误
sys.stderr.write("Error: something went wrong.")
这个例子中,我们使用sys.stderr.write()
将一行错误信息写入标准错误。在命令行中,可以将标准错误输出重定向到文件或管道中,例如:
$ python error_example.py 2> error.log
这将将标准错误重定向到名为error.log
的文件中。
6.5.2 管道
通过管道操作可以指定一个程序的输出为另一程序的输入,即将一个程序的标准输出与一个程序的标准输入相连,这种机制称为管道
管道(Pipe)是一种在不同进程之间传递数据的机制。在Python中,可以使用multiprocessing
模块中的Pipe
对象来创建管道。
Pipe
对象是一个双向管道,可以让两个进程之间进行通信。一个进程可以将数据写入管道,而另一个进程可以从管道中读取数据。以下是Pipe
对象的基本语法:
from multiprocessing import Process, Pipe
# 创建管道
parent_conn, child_conn = Pipe()
# 创建子进程
p = Process(target=child_process, args=(child_conn,))
# 启动子进程
p.start()
# 向管道中写入数据
parent_conn.send('Hello, world!')
# 从管道中读取数据
data = parent_conn.recv()
# 关闭管道
parent_conn.close()
child_conn.close()
在这个例子中,我们首先使用Pipe()
函数创建一个双向管道,parent_conn
是父进程的管道对象,child_conn
是子进程的管道对象。然后,我们使用Process
类创建一个子进程,并将child_conn
作为参数传递给子进程。在父进程中,我们使用parent_conn.send()
方法将数据写入管道,使用parent_conn.recv()
方法从管道中读取数据。在子进程中,我们可以使用child_conn.recv()
方法从管道中读取数据,使用child_conn.send()
方法将数据写入管道。最后,我们在父进程中关闭管道。
以下是一个使用管道进行进程通信的示例:
from multiprocessing import Process, Pipe
def child_process(conn):
# 从管道中读取数据
data = conn.recv()
print("Child process received:", data)
# 将数据写入管道
conn.send("Hello, parent!")
# 关闭管道
conn.close()
if __name__ == '__main__':
# 创建管道
parent_conn, child_conn = Pipe()
# 创建子进程
p = Process(target=child_process, args=(child_conn,))
# 启动子进程
p.start()
# 向管道中写入数据
parent_conn.send('Hello, child!')
# 从管道中读取数据
data = parent_conn.recv()
print("Parent process received:", data)
# 等待子进程结束
p.join()
# 关闭管道
parent_conn.close()
child_conn.close()
)
if name == ‘main’:
# 创建管道
parent_conn, child_conn = Pipe()
# 创建子进程
p = Process(target=child_process, args=(child_conn,))
# 启动子进程
p.start()
# 向管道中写入数据
parent_conn.send('Hello, child!')
# 从管道中读取数据
data = parent_conn.recv()
print("Parent process received:", data)
# 等待子进程结束
p.join()
# 关闭管道
parent_conn.close()
child_conn.close()
在这个例子中,我们创建了一个子进程,并使用管道进行进程通信。在子进程中,我们使用`conn.recv()`方法从管道中读取数据,并使用`conn.send()`方法将数据写入管道。在父进程中,我们使用`parent_conn.send()`方法将数据写入管道,并使用`parent_conn.recv()`方法从管道中读取数据。最后,我们使用`join()`方法等待子进程结束,并关闭管道。