Python之hello, world

系列文章目录

Python之hello, world


文章目录

  • 系列文章目录
  • 前言
  • 一、如何在终端输出日志
  • 二、关于sys.stdout
  • 三、关于print
  • 总结


前言

在屏幕上打印出“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打印的完整代码:

#!/usr/bin/env python
import sys

if __name__ == "__main__":
    sys.stdout.write("hello, world\n")

第一行#!/usr/bin/env python只在Linux/Unix场景下生效,当其出现在脚本语言的第一行时,用来指定本脚本用什么解释器来执行。此时./.py等同于python .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用于输出。可以直接将他们重定向至其他对象而改变输入输出的行为。读者可以参考以下代码体验这种变化:

#!/usr/bin/env python
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将无法复现此情况):

#!/usr/bin/env python
import sys
import time


def function_0():
	# 此函数会在1.3秒后输出“hello, world”
    for c in "hello, world\n":
        sys.stdout.write(c)
        time.sleep(0.1)


def function_1():
	# 此函数会每隔0.1秒增加输出一个字符,直至输完“hello, world”
    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): # known special case of print
    """
    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的逻辑等效于如下函数定义:

#!/usr/bin/env python
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输出流的简单讨论。后续文章将对本文中提到的模块、内建函数、标准库、魔法函数等知识点进行展开。如有遗漏或描述不准确的地方还请大家指正。

你可能感兴趣的:(Python,python,linux,开发语言)