系列文章目录
Python之hello, world
前言
在屏幕上打印出“hello, world”是大多数程序员学编程时第一课的内容。本文以“hello, world”为例,浅谈python编程的基本结构和语法。建议读者使用python=3.6及以上的版本。
一、如何在终端输出日志
目前常见的方法有两种:print("hello, world") 或sys.stdout.write("hello, world\n") 。 print 是python的一个内建函数(或内置函数,buildin),其功能是将输入变量打印到流(stream)中,默认流使用sys.stdout 。也就是说,默认情况下使用print,最后还是会调用到sys.stdout.write。 以下是用sys.stdout.write 打印的完整代码:
import sys
if __name__ == "__main__":
sys.stdout.write("hello, world\n")
第一行#!/usr/bin/env python 只在Linux/Unix场景下生效,当其出现在脚本语言的第一行时,用来指定本脚本用什么解释器来执行。此时./<filename>.py 等同于python <filename>.py 第二行inport 用来导入python模块,可以是python的标准库、用pip安装的第三方库或额外添加的路径(sys.path.append)下的模块。 第四行if __name__ == "__main__": 用来设定脚本被直接执行时的行为。当脚本文件被直接执行时,__name__的值为“__main__”;当脚本文件被当作模块引用时,__name__的值为本模块名。 另外,sys.stdout.write 的输入参数必须是str 类型或者bytes 类型。
二、关于sys.stdout
stdin(标准输入)、stdout(标准输出)和stderr(标准错误)是与标准I/O 流对应的流对象,是内建在每一个UNIX系统中的管道。 stdin.readline用于接收输入,stdout.write、stderr.write用于输出。可以直接将他们重定向至其他对象而改变输入输出的行为。读者可以参考以下代码体验这种变化:
import sys
import traceback
if __name__ == '__main__':
sys.stdout = open("stdout.txt", "w")
sys.stderr = open("stderr.txt", "w")
try:
1 / 0
except Exception as e:
traceback.print_exc()
print(e)
另外,在默认情况下stdout是行缓冲的,他的输出会放在一个buffer里面,直到换行时才会输出到屏幕。 可以通过调用sys.stdout.flush 让stdout无缓冲输出,读者可以比较一下示例中的两个函数来感受这种差异(请在Ubuntu-terminal、Windows-console等测试,例如pycharm将无法复现此情况):
import sys
import time
def function_0():
for c in "hello, world\n":
sys.stdout.write(c)
time.sleep(0.1)
def function_1():
for c in "hello, world\n":
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(0.1)
if __name__ == '__main__':
sys.stdout.write("function_0 start:\n")
function_0()
sys.stdout.write("function_1 start:\n")
function_1()
三、关于print
print函数的接口说明如下:
def print(self, *args, sep=' ', end='\n', file=None):
"""
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
"""
pass
它将逐个打印value的值到file中,value之间用sep连接,末尾添加end。当设置fulsh为True时,每打印一个value就会调用一次file.flush()。
- *args:这里args本身是一个元组(tuple),“*”是迭代拆包运算符。
*(value_0, value_1, ...) 等效于value_0, value_1, ... 。print会逐个调用value的__str__() 函数以获取其字符串表达。类似于__xxx__()的函数称之为魔法函数(Magic Methods),是python中十分重要的语法。 - sep:连接两个value的字符串,默认为一个字符;
- end:print最末尾的字符串,默认为一个换行符;
- file:输出对象,默认为sys.stdout,有时也会设置为可写的文件对象。print实际调用的是file.write接口;
- flush:如果flush为True,每打印一个value就会调用一次file.flush()。其效果请看上一段的
sys.stdout.flush() 。
print的逻辑等效于如下函数定义:
import sys
def print_replace(*args, sep=' ', end='\n', file=None, flush=False):
"""
:param args: prints the values to a stream, or to sys.stdout by default.
:param sep: string inserted between values, default a space.
:param end: string appended after the last value, default a newline.
:param file: a file-like object (stream); defaults to the current sys.stdout.
:param flush: whether to forcibly flush the stream.
:return:
"""
if file is None:
file = sys.stdout
need_sep = False
for value in args:
if need_sep:
file.write(sep)
need_sep = True
file.write(value.__str__())
if flush:
file.flush()
file.write(end)
if __name__ == '__main__':
print_replace("hello, world", None, sep="; ")
总结
以上就是围绕“hello, world”展开的对python输出流的简单讨论。后续文章将对本文中提到的模块、内建函数、标准库、魔法函数等知识点进行展开。如有遗漏或描述不准确的地方还请大家指正。
|