为什么print在python3中变成了函数?
转自:http://www.codingpy.com/article/why-print-became-a-function-in-python-3/
在Python 2中,print是一个语句(statement);而在Python 3中变成了函数(function)。很多Python用户都会问,为什么Python 3将print变成了函数呢?本文就是Python核心开发者Brett Cannon对此的解释。
今年初Python决定迁移到Github,就是由Brett Cannon征求Python社区的意见后作出的。他对此也作出了解释。
print语句与print函数的区别
print语句
在Python 2中,print语句最简单的使用形式就是print A
,这相当于执行了sys.stdout.write(str(A) + '\n')
。如果你以逗号为分隔符,传递额外的参数(argument),这些参数会被传递至str()
函数,最终打印时每个参数之间会空一格。例如,print A, B, C
相当于sys.stdout.write(' '.join(map(str, [A, B, C])) + '\n')
。如果print语句的最后再加上一个逗号,那么就不会再添加断行符(\n
),也就是说:print A
相当于sys.stdout.write(str(A))
。
从 2.0版本开始,Python引入了print >>
的语法,作用是重定向print
语句最终输出字符串的文件。例如,print >> output, A
相当于output.write(str(A) + '\n')
。
print函数
如果用Python来实现print函数,它的函数定义应该是这样的:
import sys def print(*objects, sep=None, end=None, file=None, flush=False):
"""A Python translation of the C code for builtins.print(). """
if sep is None:
sep = ' '
if end is None:
end = '\n'
if file is None:
file = sys.stdout
file.write(sep.join(map(str, objects)) + end)
if flush:
file.flush()
从上面的代码中,我们可以发现:Python 3中的print函数实现了print语句的所有特性。
print A == print(A)
print A, B, C == print(A, B, C)
print A, == print(A, end='')
print >> output, A == print(A, file=output)
从上面的示例代码中我们就可以看出,使用print函数有明显的好处:与使用print语句相比,我们现在能够指定其他的分隔符(separator)和结束符(end string)。
关键在于灵活性
将print变成函数的真正巧妙之处在与灵活性,但这点并不容易被人发觉。print成为函数之后,给Python用户和Python开发团队带来了很大的灵活性。对于用户来说,这可以让你把print
当作表达式(expression)使用;相比之下,print语句就只能作为语句使用。举个例子,假设你想在每一行后面打印一个省略号(ellipsis),表示这行尚未结束。使用print语句的话,你有两种选择:
# 手动实现 ...
print A, '...' # 可复用的实现(这种方式也适用于print函数) ...
def ellipsis_print(*args):
for arg in args:
print arg, '',
print '...'
但是在Python 3中,你可以选择更好的解决方式:
# 手动实现 ...
print(A, end='...\n') # 多个可复用的解决方案,利用print语句无法实现...
ellipsis_print = lambda *args, **kwargs: print(*args, **kwargs, end='...\n')
# 或者 ...
import functools
ellipsis_print = functools.partial(print, end='...\n')
换句话说,变成函数之后,print
就可以组件化了,作为语句的print
是无法支持的。还有,你还可以编写自己喜欢的print
函数,将其赋值给builtins.print
,就可以覆盖掉自带的函数实现了。这一点在Python 2中是不可能实现的。
对于Python开发团队来说,他们不必再从语法层面来实现print
的相关功能了。例如,如果你想让print
语句也一样可以灵活地支持指定分隔符,你要怎样去实现呢?这会是一个相当难解决的设计难题。但是如果print变成了函数,只需要新增一个参数就解决了。在Python中,函数可以接受任意数量的参数,这比从底层实现语法带来的灵活性要大的多。
我们还要注意,语法实现应该仅限于那些非这样做不可的功能,或者是以语法形式实现后,大幅提高了可读性的功能。在print
这个案例中,print A
与print(A)
之间的区别可以忽略不计,因此并没有影响可读性。而且,由于我们能够完全将print
语句替换为函数,对于Python语言的功能性也没有损失。这就是为什么将print
变成函数的原因。
为什么print在python3中变成了函数?的更多相关文章
- python3中的 zip()函数 和python2中的 zip()函数 的区别
python3中的 zip()函数 和python2中的 zip()函数 的区别: 描述: zip() 函数用于将可迭代对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象. ...
- Python3中的super()函数详解
关于Python3中的super()函数 我们都知道,在Python3中子类在继承父类的时候,当子类中的方法与父类中的方法重名时,子类中的方法会覆盖父类中的方法, 那么,如果我们想实现同时调用父类和子 ...
- Python3中的字符串函数学习总结
这篇文章主要介绍了Python3中的字符串函数学习总结,本文讲解了格式化类方法.查找 & 替换类方法.拆分 & 组合类方法等内容,需要的朋友可以参考下. Sequence Types ...
- python3中的range函数返回的是列表吗?
注意,这里说的Python3里面的range函数,和Python2是不同的,返回的不是列表,是可迭代对象. 在python3中,如果执行下面的语句 print(range(10)) 得到结果是 ran ...
- python3中的zip函数(转)
原文地址:https://www.cnblogs.com/qqhfeng/p/5267352.html 在window,显示变量 print(x);而在linux中 print x 例如,有两个列表: ...
- python3中的range函数
奇怪的现象 在paython3中 print(range(10)) 得出的结果是 range(0,10) ,而不是[0,1,2,3,4,5,6,7,8,9] ,为什么呢? 官网原话: In many ...
- python3中的zip函数
zip函数的作用: zip函数接受任意多个可迭代对象作为参数,将对象中对应的元素打包成一个tuple,然后返回一个可迭代的zip对象. 这个可迭代对象可以使用循环的方式列出其元素 若多个可迭代对象的长 ...
- Python3中,map()函数、filter()函数、reduce()函数的比较
1.map(function,iterable):function为函数,或者lambda表达式,iterable是可迭代的序列,即对iterable中的每个item执行一遍function或者lam ...
- python3中一句话定义函数
import math as marea=lambda r:r**2*m.pi #定义一个计算圆的面积的函数area(8) 显示结果 201.06192982974676
随机推荐
- Google C++单元测试框架---Gtest框架简介(译文)
一.设置一个新的测试项目 在用google test写测试项目之前,需要先编译gtest到library库并将测试与其链接.我们为一些流行的构建系统提供了构建文件: msvc/ for Visual ...
- Play Framework 完整实现一个APP(十)
1.定制Comment列表 新增加Comment list页面,执行命令行 > play crud:ov --template Comments/list 会生成/app/views/Comme ...
- yii2 实战教程之如何安装
作者:白狼 出处:http://www.manks.top/document/install.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...
- SqlServer数据类型
Character 字符串: 数据类型 描述 存储 char(n) 固定长度的字符串.最多 8,000 个字符. n varchar(n) 可变长度的字符串.最多 8,000 个字符. varch ...
- ORACLE表空间管理维护
1:表空间概念 在ORACLE数据库中,所有数据从逻辑结构上看都是存放在表空间当中,当然表空间下还有段.区.块等逻辑结构.从物理结构上看是放在数据文件中.一个表空间可由多个数据文件组成. 如下图所示, ...
- ORA-12516:TNS:listener could not find available handler with matching protocol stack
应用程序连接测试数据库时报ORA-12516:TNS:listener could not find available handler with matching protocol stack 检查 ...
- Linux SendMail发送邮件失败诊断案例(二)
Linux上Sendmail经常由于一些配置问题,导致邮件发送失败,下面整理.收集了一些邮件发送失败.异常的案例. 案例1:在新服务器上测试sendmail发送邮件时,发现邮件发送不成功,检查/var ...
- 《java JDK7 学习笔记》之Collection
一.使用Collection 收集对象 1.认识Collection架构 Java SE提供了满足各种需求的API,在使用这些API前,建议先了解其继承与接口操作架构,才能了解何时使用哪个类,以及类之 ...
- MongoDB学习笔记~自己封装的Curd操作(查询集合对象属性,更新集合对象)
回到目录 我不得不说,mongodb官方驱动在与.net结合上做的不是很好,不是很理想,所以,我决定对它进行了二次封装,这是显得很必然了,每个人都希望使用简单的对象,而对使用复杂,麻烦,容易出错的对象 ...
- 使用Sqoop从MySQL导入数据到Hive和HBase 及近期感悟
使用Sqoop从MySQL导入数据到Hive和HBase 及近期感悟 Sqoop 大数据 Hive HBase ETL 使用Sqoop从MySQL导入数据到Hive和HBase 及近期感悟 基础环境 ...