今天复习 Python 的输入输出,看到之前的笔记只写了 print 的底层是 sys.stdout, 而没有再细说。于是,心想它是怎么使用 sys.stdout 实现的呢? 于是又仔细研究了一下 python 函数的各个参数,遂自己写了一个 print。 就当练习语法和玩耍了,哈哈。

知识点

  1. 多值参数 一个 *: 元组; 两个星 *: 字典

  2. 列表推导式

  3. sys.stdout 标准输出流

  4. Python 类型标注支持

  5. if-else 表达式,还是 or 写的过程中, 我本来准备将 file 参数设置成 None 的, 因为按理说,可变对象参数需要使用 None 作为的默认值,从而避免对编译时生成的默认参数对象进行修改,造成意外事故。

    如果要使用 file=None 的话,那输出那里就需要判断一下

    1
    2
    3
    4
    if file:
    file.write(output_content)
    else:
    sys.stdout.write(output_content)

    但是,感觉很不简洁,于是使用 or 进行条件判断,并好奇 if-else 和 or 的优劣,就搜索到了 stackoverflow 的文章,还是 or 性能好。

    1
    2
    sys.stdout = file or sys.stdout
    sys.stdout.write(output_content)

  6. 最终我又换成了 file=sys.stdout,根据:

    1. stackoverflow 一篇文章

    2. Python 官方文档 print 默认参数

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/bin/env python
# coding=utf-8
import sys
import os


def my_print(*obj, sep: str = " ", end: str = "\n", file=sys.stdout, flush: bool = False) -> None:

str_converted = [str(obj_item) for obj_item in obj]
output_content = sep.join(str_converted)+end

file.write(output_content)

if flush:
sys.stdout.flush()


def main():
# 使用测试
my_print("You", "Me", sep=" ^--^ ", end="\nGo!\n")
my_print([1, 2, 3, 4], (1, 2, 3), {
"name": "Violetu", "sex": "male"}, sep="\n", end="\nThis is the end!\n")
print("-"*30)

filename = "test.txt"
with open(filename, "w") as fp:
my_print(f"I'm the text written to {filename}", file=fp)

os.system(f"cat {filename}")


if __name__ == "__main__":
main()

参考资料

  1. sys.stdout as default function argument
  2. if-else vs “or” operation for None-check