转载 为什么print在Python 3中变成了函数?
转载自编程派http://codingpy.com/article/why-print-became-a-function-in-python-3/
原作者:Brett Cannon
原文链接:http://www.snarky.ca/why-print-became-a-function-in-python-3
译者:EarlGrey@编程派
在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在Python 3中变成了函数?的更多相关文章
- 嵌入Python系列 | 调用Python模块中无参数函数
开发环境 Python版本:3.6.4 (32-bit) 编辑器:Visual Studio Code C++环境:Visual Studio 2013 需求说明 在用VS2013编写的Win32程序 ...
- python列表中的pop函数
再python的列表中,有许多的内置方法,而在这里我主要向大家介绍一下pop函数. pop函数主要是用于删除列表中的数据.而其删除值时会返回删除的值.如果没有参数传入时, 则会默认认为删除列表的最后一 ...
- python 类中的某个函数作为装饰器
在python的类中,制作一个装饰器的函数, class A: def wrapper(func): ###装饰器 def wrapped(self,*arg,**kwargs) ... return ...
- python之类中的super函数
作用 实现代码重用 思考:super真的只是调用父类么? super函数是按照mro算法去调用的,不bb上代码: class A: def __init__(self): print('A') cla ...
- Python学习过程中各个难点---函数篇
对于函数,我一直分不清局部变量与全局变量,今天又好好研究了下,终于搞清楚了. 例子: 其次对于global这个关键字我也是一知半解的状态,之前整个人都是懵懵的,现在搞明白了 匿名函数: 匿名函数使用关 ...
- 为什么print在python3中变成了函数?
转自:http://www.codingpy.com/article/why-print-became-a-function-in-python-3/ 在Python 2中,print是一个语句(st ...
- [转载]python中multiprocessing.pool函数介绍
原文地址:http://blog.sina.com.cn/s/blog_5fa432b40101kwpi.html 作者:龙峰 摘自:http://hi.baidu.com/xjtukanif/blo ...
- 【转载】Python编程中常用的12种基础知识总结
Python编程中常用的12种基础知识总结:正则表达式替换,遍历目录方法,列表按列排序.去重,字典排序,字典.列表.字符串互转,时间对象操作,命令行参数解析(getopt),print 格式化输出,进 ...
- 【转载】路径双反斜杠!!!Python IDLE或Python shell中切换路径 切换目录os.chdir("C:\\python37\\2019pythonshel37\\diedai")
Python IDLE或shell中切换路径在Python自带的编辑器IDLE中或者python shell中不能使用cd命令,那么跳到目标路径呢.方法是使用os包下的相关函数实现路径切换功能. im ...
随机推荐
- 铁大快捷记账Alpha版使用说明书
一. 引言 (1) 编写目的 (2) 参考资料 (3) 术语和缩写词 二. 网站概述 (1) 网站用途 (2) 网站运行 三. 网站使用过程 (1)网站登录 (2) 功能说明 一.引言 (1)编写目的 ...
- C语言版本:顺序表的实现
seqlist.h #ifndef __SEQLIST_H__ #define __SEQLIST_H__ #include<cstdio> #include<malloc.h> ...
- 剑指offer:从上往下打印二叉树
题目描述: 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 解题思路: 实际就是二叉树的中序遍历问题.之前在leetcode刷过类似题目. 利用队列完成即可. 代码: /* struct Tr ...
- TensorFlow常用API汇总
1.tensorflow的基本运作为了快速的熟悉TensorFlow编程,下面从一段简单的代码开始: import tensorflow as tf #定义‘符号’变量,也称为占位符 a = tf.p ...
- ElasticSearch 2 (11) - 节点调优(ElasticSearch性能)
ElasticSearch 2 (11) - 节点调优(ElasticSearch性能) 摘要 一个ElasticSearch集群需要多少个节点很难用一种明确的方式回答,但是,我们可以将问题细化成一下 ...
- opencv图像识别技术在自动化测试中的应用
在自动化测试中,基于xpath.js选择器.css选择器进行元素定位及判定的技术已经比较成熟.在实际应用中,无论是web端还是移动端,仍有很多时候需要根据页面内容.页面中的图像进行定位及判定,这里介绍 ...
- 二叉树的Java实现及特点总结
二叉树是一种非常重要的数据结构,它同时具有数组和链表各自的特点:它可以像数组一样快速查找,也可以像链表一样快速添加.但是他也有自己的缺点:删除操作复杂. 我们先介绍一些关于二叉树的概念名词. 二叉树: ...
- BZOJ 3171 循环格(费用流)
题意 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位置(r,c),你可以沿着箭头防线在格子间行走.即如果(r ...
- 【BZOJ3139】[HNOI2013]比赛(搜索)
[BZOJ3139][HNOI2013]比赛(搜索) 题面 BZOJ 洛谷 题解 双倍经验
- Problem A: 种树 解题报告
Problem A: 种树 Description 很久很久以前,一个蒟蒻种了一棵会提问的树,树有\(n\)个节点,每个节点有一个权值,现在树给出\(m\)组询问,每次询问两个值:树上一组点对\((x ...