为什么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 Aprint(A)之间的区别可以忽略不计,因此并没有影响可读性。而且,由于我们能够完全将print语句替换为函数,对于Python语言的功能性也没有损失。这就是为什么将print变成函数的原因。

时间: 2024-12-27 20:51:19

为什么print在python3中变成了函数?的相关文章

Python3中的super()函数详解

关于Python3中的super()函数 我们都知道,在Python3中子类在继承父类的时候,当子类中的方法与父类中的方法重名时,子类中的方法会覆盖父类中的方法, 那么,如果我们想实现同时调用父类和子类中的同名方法,就需要使用到super()这个函数,用法为super().函数名() 下面是一个例子: class A1(): def go(self): print("go A1 go") class A2(): def go(self): print("go A2 go&qu

python3中的 zip()函数 和python2中的 zip()函数 的区别

python3中的 zip()函数 和python2中的 zip()函数 的区别: 描述: zip() 函数用于将可迭代对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象. 如果各个可迭代对象的元素个数不一致,则返回的对象长度与最短的可迭代对象相同. 利用 * 号操作符,与zip相反,进行解压. zip() 函数语法: zip(iterable1,iterable2, ...) 参数说明: iterable -- 一个或多个可迭代对象(字符串.列表.元祖.字典) 返回

python3中的range函数返回的是列表吗?

注意,这里说的Python3里面的range函数,和Python2是不同的,返回的不是列表,是可迭代对象. 在python3中,如果执行下面的语句 print(range(10)) 得到结果是 range(0,10) ,而不是期望的[0,1,2,3,4,5,6,7,8,9].但是如果换一种方式 print(list(range(10))) 得到的结果却是 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 那为什么会这样呢?其实在Python3中range()函数返回的对象很像一个列表

python3中的range函数

奇怪的现象 在paython3中 print(range(10)) 得出的结果是 range(0,10) ,而不是[0,1,2,3,4,5,6,7,8,9] ,为什么呢? 官网原话: In many ways the object returned by range() behaves as if it is a list, but in fact it isn’t. It is an object which returns the successive items of the desire

python3中的filter()函数

filter() 函数是一个对于可迭代对象的过滤器,过滤掉不符合条件的元素,返回的是一个迭代器,如果要转换为列表,可以使用 list() 来转换.该函数接收两个参数,第一个为函数的引用或者None,第二个为可迭代对象,可迭代对象中的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到迭代器中下面看下fiter()的用法:第一个参数为None: [Python] 纯文本查看 复制代码 ? 1 2 3 4 my_list = [1, '', 2, '

python3中的zip函数

zip函数的作用: zip函数接受任意多个可迭代对象作为参数,将对象中对应的元素打包成一个tuple,然后返回一个可迭代的zip对象. 这个可迭代对象可以使用循环的方式列出其元素 若多个可迭代对象的长度不一致,则所返回的列表与长度最短的可迭代对象相同. matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] 使用*号拆分list,zip对每个list打包成tuple >>> list(zip(*matrix)) [ (1, 4, 7), (2, 5, 8

Python3中的open函数

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)     Open file and return a stream.  Raise IOError upon failure. #打开文件并返回一个流?失败则抛出IOError异常 mode:     ========= ===================================

python3中使用python2中cmp函数出现错误

在python2中我们经常会使用cmp函数来比较一些东西,但是在python3中,你再来使用这个函数的时候,发现就报错了,提示找不到这个函数,这是为啥呢? 答:新版的python已经舍弃这种用法 而在python3中,cmp函数被新的模块operater所取代. operater函数的具体用法请点击链接:https://blog.csdn.net/qq_24918869/article/details/52175886 原文地址:https://www.cnblogs.com/Lmengzi/p

12-python基础—python3中的reduce()

在 Python3 中,reduce() 函数已经被从全局名字空间里移除了,它现在被放置在 functools 模块里,需要通过引入 functools 模块来调用 reduce() 函数: from functools import reduce reduce函数会对参数序列中元素进行累积; reduce()传入的函数 f 接收两个参数; reduce函数的定义: reduce(function, sequence [, initial] ) -> value # function参数接收两个