【Python学习手册(第四版)】学习笔记11.2-表达式语句(print函数)及打印操作(重定向等)详解

news2024/12/23 17:48:24

个人总结难免疏漏,请多包涵。更多内容请查看原文。本文以及学习笔记系列仅用于个人学习、研究交流。

主要介绍表达式语句(print函数)及打印操作(重定向等)。视需要选择目录阅读。


目录

表达式语句

错误示例:原处修改

打印操作

Python 3.0的print函数

调用格式

应用

打印流重定向

重定向输出流

自动化流重定向

为什么要注意print和stdout


表达式语句

在Python中,也可以使用表达式作为语句(本身只占一行)。但是表达式结果不会存储,只有当表达式工作并作为附加的效果,这样才有意义。

通常在两种情况下表达式用作语句。

调用函数和方法

有些函数和方法会做很多工作,而不会有返回值。这种函数在其他语言中有时称为过程。因为它们不会返回你可能想保留的值,所以你可以用表达式语句调用这些函数。

在交互模式提示符下打印值

Python会在交互模式命令行中响应输入的表达式的结果。从技术上来讲,这些也是表达式语句。作为输入print语句的简写方法。

表11-4列出Python中一些常见的表达式语句的形式。函数和方法的调用写在函数/方法变量名后的括号内,具有零或多个参数的对象(其实,这就是计算对象的表达式)。

 在Python 3.0中,打印是一个函数调用而通常独自编写为一行,并且生成器函数(后续文章介绍)中的yield操作通常也编写为一条语句。

例如,尽管通常在独自一行上运行一个print调用,它像任何其他函数调用一样返回一个值(它的返回值是None,这是那些不返回任何有意义内容的函数的默认返回值):

>>> x = print('life')
life
>>> print(x)
None

注意:虽然表达式在Python中可作为语句出现,但语句不能用作表达式。

例如,Python不让把赋值语句(=)嵌入到其他表达式中。这样做的理由是为了避免常见的编码错误。当用“==”做相等测试时,不会打成“=”而意外修改变量的值。

>>> print(a = 1)
Traceback (most recent call last):
  File "<pyshell#189>", line 1, in <module>
    print(a = 1)
TypeError: 'a' is an invalid keyword argument for print()
>>> print(a == 1)
False

错误示例:原处修改

这里会引出Python工作中常犯的错误。

表达式语句通常用于执行可于原处修改列表的列表方法:

>>> l1 = [1,2]
>>> l1.append(3)
>>> l1
[1, 2, 3]

Python初学者时常把这种运算写成赋值语句,试着把L赋值给更大的列表:

>>> l = l.append(4)
>>> print(l)
None

这样做是行不通的。对列表调用append、sort或reverse这类在原处的修改的运算,一定是对列表做原处的修改,但这些方法在列表修改后并不会把列表返回。

事实上,它们返回的是None对象。如果你赋值这类运算的结果给该变量的变量名,只会丢失该列表(而且可能在此过程中被当成垃圾回收)。

>>> l

所以不要这样做。


打印操作

在Python中,print语句可以实现打印——只是对程序员友好的标准输出流的接口而已。

从技术角度来讲,这是把一个或多个对象转换为其文本表达形式,然后发送给标准输出或另一个类似文件的流。在Python中,打印与文件和流的概念紧密相连。

文件对象方法

写入文件的文件对象方法(例如,file.write(str))。打印操作是类似的,但更加专注——文件写入方法是把字符串写入到任意的文件,print默认地把对象打印到stdout流,添加了一些自动的格式化。

和文件方法不同,在使用打印操作的时候,不需要把对象转换为字符串。

标准输出流

标准输出流(通常叫做stdout)只是发送一个程序的文本输出的默认的地方。加上标准输入流和错误流,它只是脚本启动时所创建的3种数据连接中的一种。标准输出流通常映射到启动Python程序的窗口,除非它已经在操作系统的shell中重定向到一个文件或管道。

由于标准输出流在Python中可以作为内置的sys模块中的stdout文件对象使用(例如,sys.stdout),用文件的写入方法调用来模拟print成为可能。

然而,print很容易使用,这使得很容易就能把文本打印到其他文件或流。

编写打印操作的方式取决于所使用的Python的版本:

在Python 3.X中,打印是一个内置函数,用关键字参数来表示特定模式。

在Python 2.X中,打印是语句,拥有自己的特定语法。

Python 3.0的print函数

严格地讲,打印不是一种单独的语句形式。

print内置函数通常在其自身的一行中调用,但是它不会返回我们所关心的任何值(从技术上讲,它返回None)。因为它是一个常规的函数。

调用格式

从语法上讲,调用Python 3.0的print函数有如下的形式:

再来看一下源码

在这个正式的表示中,方括号中的项是可选的,并且可能会在一个给定的调用中省略,并且=后面的值都给出了参数的默认值。这个内置的函数把字符串sep所分隔开的一个或多个对象的文本表示,后面跟着的字符串end,都打印到流file中。

sep、end和file部分如果给出的话,必须作为关键字参数给定——也就是说,必须使用一种特殊的"name=value"语法来根据名称而不是位置来传递参数。

发送给这个调用的关键字参数可以以任何的从左到右的顺序显示,这些参数跟在要打印的对象的后面,并且,它们控制print操作:

  • ·sep是在每个对象的文本之间插入的一个字符串,如果没有传递的话,它默认地是一个单个的空格;传递一个空字符串将会抑制分隔符。
  • ·end是添加在打印文本末尾的一个字符串,如果没有传递的话,它默认的是一个\n换行字符。传递一个空字符串将会避免在打印的文本的末尾移动到下一个输入行——下一个print将会保持添加到当前输出行的末尾。
  • ·file指定了文本将要发送到的文件、标准流或者其他类似文件的对象;如果没有传递的话,它默认的是sys.stdout。带有一个类似文件的write(string)方法的任何对象都可以传递,但真正的文件应该已经为了输出而打开。

要打印的每个对象的文本表示,通过把该对象传递给str内置函数调用而获得;这个内置函数针对任何对象返回一个“用户友好的”显示字符串。

没有参数的时候,print函数直接把一个换行字符打印到标准输出流,它通常显示为一个空白的行。

应用

下面把各种对象类型打印到默认的标准输出流,带有一个默认的分隔符和行末格式化添加(这里都是默认值)。

>>> print()

>>> x = 'spam'
>>> y = 99
>>> z = ['egg']
>>> 
>>> print(x,y,z)
spam 99 ['egg']

这里不需要把对象转换为字符串,而在文件写入方法中则需要这么做。

默认情况下,print调用在打印的对象之间添加一个空格。要取消这个空格,给sep关键字参数发送一个空字符串,或者发送一个自己所选择的替代分隔符:

>>> print(x,y,z, sep = '') 	    #禁止分离
spam99['egg']

>>> print(x,y,z, sep = ',') 	#这里选择的是中文逗号
spam,99,['egg']
>>> 

默认情况下,print添加一个行末字符来结束输出行。可以通过向end关键字参数传递一个空字符串来抑制这一点并避免换行,或者可以传递一个自己的不同的终止符(包含一个\n符号来手动地换行):

>>> print(x,y,z, end = '')	#禁止分离
spam 99 ['egg']

>>> print(x,y,z, end = '');print(x,y,z)    #两条打印,同一行输出
spam 99 ['egg']spam 99 ['egg']

>>> print(x,y,z, end = '...\n')    #自定义
spam 99 ['egg']...
>>>

也可以组合关键字参数来指定分隔符和行末字符串——它们可以以任何顺序出现,但是必须出现在所有要打印的对象的后面:

>>> print(x,y,z, sep = '...', end = '!\n')
spam...99...['egg']!
>>> print(x,y,z, end = '!\n', sep = '...')
spam...99...['egg']!

如何使用file关键字——它在单个打印的过程中,直接把文本打印到一个输出文件或者其他的可兼容对象(这其实是流重定向的一种形式):

>>> print(x,y,z, sep = '...', end = '!\n',file = open('data.txt','w'))

>>> print(x,y,z)
spam 99 ['egg']

>>> print(open('data.txt').read())
spam...99...['egg']!

>>> 

print操作提供的分隔符和行末选项只是为了方便起见。

如果需要显示更具体的格式,不要以这种方式打印,相反,提前构建一个更复杂的字符串或者在print自身之中使用字符串工具,并一次性打印该字符串:

>>> text = '%s: %-.4f,%05d' % ('Result',3.14159,42)
>>> print(text)
Result: 3.1416,00042

>>> print('%s: %-.4f,%05d' % ('Result',3.14159,42))
Result: 3.1416,00042

打印流重定向

打印都默认地发送到标准输出流。通常发送到其他的地方也是有用的,例如发送到一个文本文件,以保存结果供以后使用和测试。事实上,在脚本中重定向一个脚本的流也是很容易做到的。

print语句只是Python的人性化的特性,提供了sys.stdout对象的简单接口,再加上一些默认的格式设置。实际上,如果想写的更复杂一些,也可以用下面这种方式编写打印操作。

>>> import sys
>>> sys.stdout.write('hello world\n')
hello world
12  #输出位数

这段程序有意调用了sys.stdout的write方法(当Python启动连接输出流的文件对象时,这个属性就会事先设置)。print语句隐藏大多数细节,提供了简单工具从而进行简单的打印任务。

重定向输出流

为什么要教你复杂的打印方式呢?等效的sys.stdout打印方式可以说是Python中常用技术的基础。

通常来说,print和sys.stdout的关系如下:

>>> print(x,y)
spam 99

#等价于下面

>>> import sys
>>> sys.stdout.write(str(x) + ' ' + str(y) + '\n')
spam 99
8
>>> 

作为较长的打印书写形式本身并没有什么用处。不过了解这就是print语句所做的事是有用处的,因为有可能把sys.stdout重新赋值给标准输出流以外的东西。换句话说,这种等效的方式提供了一种方法,可以让print语句将文字传送到其他地方。例如:

>>> import sys
>>> sys.stdout = open('log.txt','a')
>>> print(x,y)

在这里,把sys.stdout重设成已打开的文件对象(采用附加模式)。重设之后,程序中任何地方的print语句都会将文字写至文件log.txt的末尾,而不是原始的输出流。print语句将会很乐意持续地调用sys.stdout的write方法,无论sys.stdout当时引用的是什么。因为你的进程中只有一个sys模块,通过这种方式赋值sys.stdout会把程序中任何地方的每个print都进行重新定向。

甚至可以将sys.s tdout重设为非文件的对象,只要该对象有预期的协议(write方法)。当该对象是类时,打印的文字可以定位并通过任意方式进行处理。

这种重设输出列表的技巧主要用于程序原本是用print语句编写的情况。如果一开始就知道应该输出到文件中去,就可以改为调用文件的write方法。

为了将基于print的程序重定向,sys.stdout重设为修改每条print语句或者使用系统shell重定向语法提供一种方便的替代方式。

自动化流重定向

通过赋值sys.stdout而将打印文字重定向的技巧实际上非常常用。但是,上一节代码中有个潜在的问题,那就是没有直接的方式可以保存原始的输出流。

在打印至文件后,可以切换回来。因为sys.stdout只是普通的文件对象,你可以存储它,需要时恢复:

>>> import sys
>>> temp = sys.stdout    #保存以便恢复
>>> sys.stdout = open('log.txt','a')    #定向打印到文件
>>> print('life')        #打印到文件
>>> sys.stdout.close()   #关闭保存到磁盘
>>> sys.stdout = temp    #恢复原始打印
>>> 

>>> print('life')
life
>>> print(open('log.txt').read())
life

>>> 

像这样的手动保存和恢复原始的输出流包含了相当多的额外工作。因为这种操作出现的相当频繁,一个print扩展功能使得它显得多余。

在Python 3.0中,file关键字允许一个单个的print调用将其文本发送给一个文件的write方法,而不用真正地重设sys.stdout。因为这种重定向是暂时的,普通的print语句还是会继续打印到原始的输出流的。

>>> log = open('log.txt','a')
>>> x,y,z = 1,2,3
>>> print(x,y,z,file = log)
>>> a,b,c = 'lie'
>>> print(a,b,c)
l i e

如下交互会话使用了两种打印,然后把输出重定向到一个外部文件中,以验证打印了相同的文本:

除非喜欢录入,print操作通常是显示文本的最佳选择。

为什么要注意print和stdout

print语句和sys.stdout之间的等效是很重要的。这样才有可能把sys.stdout重新赋值给用户定义的对象(提供和文件相同的方法,就像write)。

因为print语句只是传送文本给sys.stdout.write方法,可以把sys.stdout赋值给一个对象,而由该对象的write方法通过任意方式处理文字,通过这个对象捕捉程序中打印的文本。

例如,你可以传送打印的文字给GUI窗口,或者定义一个有write方法的对象,它会做所需要的发送工作,从而可以提供给多个目的地。

行得通是因为print是多态运算:sys.stdout是什么不重要,只要有个方法(接口)称为write即可。

不再需要刻意重设sys.stdout——常规的print仍然定向到stdout流:

Python内置的raw_input()函数会从sys.stdin文件读入,可以用类似方式拦截对读取的请求:使用类来实现类似文件的read方法。

注意:因为打印的文字进入stdout流,这也是在CGI脚本中打印HTML的方式。这也可以在操作系统命令行中对Python脚本的输入和输出进行像往常一样的重定向:

Python的打印操作重定向工具实质上是这些Shell语法形式的纯Python替代。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1963229.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实验3-7 统计学生成绩

//实验3-7 统计学生成绩 /* 本题要求编写程序读入N个学生的百分制成绩&#xff0c;统计五分制成绩的分布。 百分制成绩到五分制成绩的转换规则&#xff1a;大于等于90分为A&#xff1b;小于90且大于等于80为B&#xff1b;小于80且大于等于70为C&#xff1b;小于70且大于等于60为…

相机标定(Camera Calibration)

什么是 相机标定&#xff08;Camera Calibration&#xff09;&#xff1f; 相机标定&#xff08;CameraCalibration&#xff09;是确定相机内部参数&#xff08;如焦距、光学中心、畸变系数等&#xff09;和外部参数&#xff08;如相机在世界坐标系中的位置和姿态&#xff09;的…

黑马头条vue2.0项目实战(三)——个人中心功能的实现

1. Tabbar 处理 通过分析页面&#xff0c;可以看到&#xff0c;首页、问答、视频、我的 都使用的是同一个底部标签栏&#xff0c;我们没必要在每个页面中都写一个&#xff0c;所以为了通用方便&#xff0c;我们可以使用 Vue Router 的嵌套路由来处理。 父路由&#xff1a;一个…

激发潜能,Vatee万腾平台驱动企业持续发展

在当今这个日新月异的商业环境中&#xff0c;企业要想保持竞争力并实现持续发展&#xff0c;就必须不断挖掘自身潜能&#xff0c;探索新的增长点。而Vatee万腾平台&#xff0c;正是这样一位能够激发企业潜能、驱动其持续发展的强大伙伴。 一、智能化赋能&#xff0c;解锁企业潜…

了解ISO 22301:业务连续性管理的关键

在当今全球化和复杂化的商业环境中&#xff0c;企业面临着各种潜在的风险和灾难&#xff0c;这些可能对其运营和声誉造成严重影响。为了有效地应对这些挑战并保障持续经营&#xff0c;国际标准化组织&#xff08;ISO&#xff09;引入了ISO 22301标准&#xff0c;这是一项专注于…

智能制造与工业物联网CC2530——定时器查询和中断

一、项目目的&#xff1a; 熟悉 ZigBee 模块相关硬件接口。使用 IAR 开发环境设计程序&#xff0c;学习 CC2530 定时器的使用&#xff0c;利用 CC2530 的定时器 T1 查询方式控制 LED 周期性闪烁。 二、项目原理&#xff1a; LED及按键原理图&#xff0c;如下图所示&#xff…

使用“阿里云人工智能平台 PAI”制作数字人

体验 阿里云人工智能平台 PAI PAI-DSW免费试用 https://free.aliyun.com/?spm5176.14066474.J_5834642020.5.7b34754cmRbYhg&productCodelearn https://help.aliyun.com/document_detail/2261126.html 体验PAI-DSW https://help.aliyun.com/document_detail/2261126.…

一文详解香港机房服务器干什么用的

香港机房服务器干什么用的&#xff1f;香港机房服务器是用于数据存储和备份、网络服务、数据处理与分析、云计算服务、游戏托管服务、其他服务等。香港机房服务器在现代互联网业务中扮演着至关重要的角色&#xff0c;其主要用途可以归纳为以下几个方面&#xff1a; 1、数据存储…

卡拉OK歌唱比赛活动策划方案

一、活动详细策划 &#xff08;一&#xff09;、前期工作准备 1、制定详细的策划方案、比赛流程&#xff0c;通知稿。 2、收集各参赛选手详细资料在选手上台前展示出&#xff0c;让各评委及嘉宾对选手有个初步认识。 3、各工作组准备好相关道具&#xff08;音响、无线话筒、低…

数据大脑智慧工厂数据平台建设方案(可编辑60页PPT)

引言&#xff1a;随着工业4.0时代的到来&#xff0c;智能制造已成为推动产业升级的核心引擎。为了进一步提升生产效率、优化资源配置、实现精准决策与个性化定制&#xff0c;构建一套高效、智能的数据大脑智慧工厂数据平台显得尤为重要。 方案介绍&#xff1a; 在数字化转型的…

05.FreeRTOS任务挂起与恢复

05. FreeRTOS任务挂起与任务恢复 1. FreeRTOS 挂起和恢复任务相关 API 函数 函数描述vTaskSuspend()挂起任务vTaskResume()恢复被挂起的任务xTaskResumeFromISR()在中断中恢复被挂起的任务 函数vTaskSuspend() 此函数用于挂起任务&#xff0c;若使用此函数&#xff0c;需要在…

【Docker】Namespace 空间隔离实战

一、实战目的 了解隔离能力并不是 Docker 提供的&#xff0c;而是操作系统内核提供基本能力。 二、基础知识 1、dd 命令详解 Linux dd 命令用于读取、转换并输出数据。 dd 可从标准输入或文件中读取数据&#xff0c;根据指定的格式来转换数据&#xff0c;再输出到文件、…

直流电表常见的应用有哪些

直流电表作为电力系统中不可或缺的计量工具&#xff0c;其应用广泛且多样化。以下是对直流电表常见应用的详细归纳&#xff1a; 一、新能源发电系统 1. 太阳能光伏发电 应用背景&#xff1a;太阳能光伏发电系统通过太阳能电池板将光能转化为直流电能。直流电表在这一系统中扮…

浪潮NF5280M4虚拟磁盘OFFLINE和磁盘状态为“Frn-Bad”与“UB”故障处理

客户托管设备的机房异常断电&#xff0c;导致6台浪潮NF5280M4的系统无法访问&#xff0c;系统所在的RAID组中的2块磁盘全部亮故障灯。 通过设备管理界面检查&#xff0c;发现逻辑磁盘处于Offline状态&#xff1a; 物理磁盘也处于Offline状态&#xff1a; 进入BIOS RAID配置…

介绍几种 iutils.dll丢失的解决办法,iutils.dll文件详细介绍

电脑中经常会出现 iutils.dll文件丢失的情况&#xff0c;所以如果电脑中缺失 iutils.dll文件会让大家很苦恼&#xff0c;那么 iutils.dll丢失有什么解决办法呢&#xff1f;今天就给大家介绍几种 iutils.dll丢失的解决办法。 1. iutils.dll 文件的来源 iutils.dll 是一个动态链…

npm 修改 淘宝源

aliyun ECS npm 源也不顺畅了&#xff0c;哎 &#x1f611; npm config get registrynpm config set registry https://registry.npmmirror.com喜欢或对你有帮助&#xff0c;点个赞吧&#xff0c;自己先点个嘿嘿。 有错误或者疑问还请评论指出。 我的个人网站 点击访问 hongw…

暑假时光的趣味新选择:《米小圈漫画历史》的魅力探秘

当暑假的炎炎夏日来临&#xff0c;许多家长都会面临一个共同的挑战&#xff1a;如何让孩子远离手机屏幕&#xff0c;找到既有趣又有教育意义的活动。作为一名父母&#xff0c;我被这个问题所困扰。看着孩子一整天沉浸在电子设备中&#xff0c;我深知这不仅会影响他们的视力&…

web程序员转大模型岗位,零基础入门到精通非常详细,收藏我这一篇就够了

从Web程序员转型到大模型岗位&#xff0c;需要掌握一系列新技能和知识。以下是一个详细的攻略&#xff1a; 了解大模型基础&#xff1a; 学习大模型的基本概念&#xff0c;如Transformer架构、自注意力机制等。 阅读相关论文&#xff0c;如“Attention is All You Need”等。 …

Debug-019-git reflog的两种使用场景

前情&#xff1a;最近在开发项目中对版本管理有了新的理解&#xff0c;感觉在这方面有了新的收获。同时学习了一个新的git指令&#xff1a;git reflog 实际了解之后&#xff0c;发现这个指令不是很常用&#xff0c;但是对于特定的场景的话它还是非常比较方便 这里我列举两种我…

使用 LangChain 开发 LLM 应用(3):记忆

注: 本文是基于吴恩达《LangChain for LLM Application Development》课程的学习笔记&#xff1b;完整的课程内容以及示例代码/Jupyter笔记见&#xff1a;LangChain-for-LLM-Application-Development&#xff1b; 课程大纲 目前 LLM 基本上都有最大 Token 的限制&#xff0c;即…