完成以下问题, 表示你完成了一门编程语言的学习

1.入门

1.1 官方文档,特性和应用场景有哪些

官方文档
Python是一门简单易学, 功能强大的编程语言。
它开源, 免费, 可用于C或者C++的扩展, 或者封装
特性: 语法优雅, 动态类型, 解释运行, 部分面向对象
场景: 编写脚本, 快速构建几乎所有的小型应用,比如桌面程序, 手机程序, 任何服务器, 游戏等等

所谓部分面向对象, 就是有类, 也有内置函数, 有的类型有构造方法, 有的用函数 比如Java是严格面向对象, 所有类型都有方法 Golang 更面向组合, 更多使用函数和接口, 少量使用结构体

1.2 安装与运行

安装
官网下载安装, 完成后在中断输入 pythonx.x
运行

  • x.x 对应版本号, 比如 python3.9, 然后打印 hello world

    1. Python 3.8.1 (v3.8.1:1b293b6006, Dec 18 2019, 14:08:53)
    2. [Clang 6.0 (clang-600.0.57)] on darwin
    3. Type "help", "copyright", "credits" or "license" for more information.
    4. >>> print('hello world')
    5. hello world
  • 直接运行py文件, 如下 test.py, 在终端中输入 pythonx.x test.py

    1. if __name__ == '__main__':
    2. print('hello world')

    1.3 镜像(选答)

    安装依赖时的镜像

    1. pip install {redis} -i https://pypi.douban.com/simple

    1.4 编辑器(选答)

    Python可以使用 ipython, jupyter, VSCode, Pycharm 等
    推荐学习时使用 ipython, 写项目用 Pycharm, 两者都有提示
    前者是增强交互型shell, 后者是IDE

    1.5 包管理工具

    1. # 安装依赖库
    2. pip install requests
    3. # 指定版本
    4. pip install requests==2.6.0
    5. # 升级到最新版本
    6. pip install --upgrade requests
    7. # 卸载
    8. pip uninstall requests
    9. # 显示库的信息
    10. pip show requests
    11. # 显示安装的包
    12. pip list
    13. # 生成一个类似的已安装包列表
    14. pip freeze > requirements.txt
    15. # 从文件中安装依赖
    16. pip install -r requirements.txt

    2.基本语法

    2.1 判断

    1. # if, Python里没有switch
    2. >>> x = int(input("Please enter an integer: "))
    3. Please enter an integer: 42
    4. >>> if x < 0:
    5. ... x = 0
    6. ... print('Negative changed to zero')
    7. ... elif x == 0:
    8. ... print('Zero')
    9. ... elif x == 1:
    10. ... print('Single')
    11. ... else:
    12. ... print('More')

    2.2 循环

    ```python

    循环 items

    Strategy: Iterate over a copy

    for user, status in users.copy().items(): if status == ‘inactive’:

    1. del users[user]

Strategy: Create a new collection

active_users = {} for user, status in users.items(): if status == ‘active’: active_users[user] = status

遍历

enumerate 传入可迭代数据, 返回序列和值组成的元组

In [1]: squal = [1, 2, 4, 9, 16] In [2]: for i, v in enumerate(squal): …: print(f’index={i}, value={v}’) …: index=0, value=1 index=1, value=2 index=2, value=4 index=3, value=9 index=4, value=16

break、continue 与其他语言相同

  1. <a name="LbQY0"></a>
  2. ### 2.3 函数
  3. ```python
  4. # pass, 占位语句, Python特有
  5. def aaa():
  6. pass # 什么也不做
  7. # 函数
  8. # 使用 def 关键字, 可接收单个参数, 列表和 键值对
  9. def cheeseshop(kind, *arguments, **keywords):
  10. print("-- Do you have any", kind, "?")
  11. print("-- I'm sorry, we're all out of", kind)
  12. for arg in arguments:
  13. print(arg)
  14. print("-" * 40)
  15. for kw in keywords:
  16. print(kw, ":", keywords[kw])
  17. # 调用
  18. cheeseshop("Limburger", "It's very runny, sir.",
  19. "It's really very, VERY runny, sir.",
  20. shopkeeper="Michael Palin",
  21. client="John Cleese",
  22. sketch="Cheese Shop Sketch")
  23. # 输出
  24. '''
  25. -- Do you have any Limburger ?
  26. -- I'm sorry, we're all out of Limburger
  27. It's very runny, sir.
  28. It's really very, VERY runny, sir.
  29. ----------------------------------------
  30. shopkeeper : Michael Palin
  31. client : John Cleese
  32. sketch : Cheese Shop Sketch
  33. '''

2.4 错误与异常

  1. # 捕获异常
  2. while True:
  3. try:
  4. x = int(input("Please enter a number: "))
  5. except ValueError:
  6. print("Oops! That was no valid number. Try again...")
  7. # 可以省略异常名,以用作通配符。但应谨慎使用,这种方式很容易掩盖真正的编程错误!
  8. except:
  9. print('some error happens!')
  10. # 使用 else 子句比向 try 子句添加额外的代码要好,可以避免意外捕获非 try ... except 语句保护的代码触发的异常。
  11. else:
  12. print(f'you input {x}')
  13. # 在实际应用程序中,finally 子句对于释放外部资源(例如文件或者网络连接)非常有用,无论是否成功使用资源。
  14. finally:
  15. print("executing finally clause")
  16. # 抛出异常
  17. raise NameError('HiThere')
  18. Traceback (most recent call last):
  19. File "<stdin>", line 1, in <module>
  20. NameError: HiThere

2.5 面向对象

  1. # 类的定义
  2. # 括号中是继承的父类
  3. class Dog(FatherClass):
  4. kind = 'canine' # class variable shared by all instances
  5. def __init__(self, name):# 构造函数
  6. self.name = name # instance variable unique to each instance
  7. self.tricks = [] # creates a new empty list for each dog
  8. # 方法, 都要加 self 关键字
  9. def add_trick(self, trick):
  10. self.tricks.append(trick)

实例变量与类变量
一般来说,实例变量用于每个实例的唯一数据,而类变量用于类的所有实例共享的属性和方法
正确的类设计应该使用实例变量, 不使用类变量
私有变量
那种仅限从一个对象内部访问的“私有”实例变量在 Python 中并不存在
但是,大多数 Python 代码都遵循这样一个约定:带有一个下划线的名称 (例如 _spam) 应该被当作是 API 的非公有部分 (无论它是函数、方法或是数据成员)。 这应当被视为一个实现细节,可能不经通知即加以改变

3.基本数据类型

3.1 数字

  1. # this is the first comment
  2. spam = 1 # and this is the second comment
  3. # ... and now a third!
  4. text = "# This is not a comment because it's inside quotes."
  5. # 加减乘除,取余,取整
  6. >>> 2 + 2
  7. 4
  8. >>> 50 - 5*6
  9. 20
  10. >>> (50 - 5*6) / 4
  11. 5.0
  12. >>> 8 / 5 # division always returns a floating point number
  13. 1.6
  14. >>> 17 / 3 # classic division returns a float
  15. 5.666666666666667
  16. >>> 17 // 3 # floor division discards the fractional part
  17. 5
  18. >>> 17 % 3 # the % operator returns the remainder of the division
  19. 2
  20. # 取小数点后两位
  21. >>> round(123.345, 2)
  22. 123.34
  23. # 整数与小数转换
  24. In [1]: int(123.4)
  25. Out[1]: 123
  26. In [2]: float(123)
  27. Out[2]: 123.0
  28. # 指数
  29. >>> 5 ** 2 # 5 squared
  30. 25
  31. >>> 2 ** 7 # 2 to the power of 7
  32. 128
  33. # 十进制转其他进制
  34. # 注意结果都是字符串
  35. In [24]: deci = 100
  36. # 二进制
  37. In [26]: bin(deci)
  38. Out[26]: '0b1100100'
  39. # 十六进制
  40. In [25]: hex(deci)
  41. Out[25]: '0x64'
  42. # 八进制
  43. In [27]: oct(deci)
  44. Out[27]: '0o144'
  45. # 其他进制转十进制
  46. # 结果是数字
  47. # 二进制
  48. In [28]: int('0b1000', 2)
  49. Out[28]: 8
  50. # 八进制
  51. In [29]: int('0o1000', 8)
  52. Out[29]: 512
  53. # 十六进制
  54. In [31]: int('0x20', 16)
  55. Out[31]: 32

3.2 字符

  1. # 单引号和双引号都可以
  2. In [4]: print('hello lisay')
  3. hello lisay
  4. # 单引号中的双引号可以直接显示,不用转义
  5. # 同理反过来也一样
  6. In [6]: print('"hi", I said')
  7. "hi", I said
  8. # 转义字符
  9. In [7]: print('hi \n i said')
  10. hi
  11. i said
  12. # 显示原始字符, 加个 r
  13. In [8]: print(r'hi \n i said')
  14. hi \n i said
  15. # 多行输出, 用三个单引号或者双引号, 并且加上 \
  16. # 反斜杠表示不包含本行的换行符
  17. In [9]: print("""\
  18. ...: Usage: thingy [OPTIONS]
  19. ...: -h Display this usage message
  20. ...: -H hostname Hostname to connect to
  21. ...: """)
  22. Usage: thingy [OPTIONS]
  23. -h Display this usage message
  24. -H hostname Hostname to connect to
  25. # 字符拼接
  26. # 可以使用 + 号
  27. In [13]: print('py' + 'thon')
  28. python
  29. # 也可以用join
  30. In [61]: 'python'.join(['a', 'b'])
  31. Out[61]: 'apythonb'
  32. # 格式化输出
  33. In [15]: print("{} can be {}".format("strings", "interpolated"))
  34. strings can be interpolated
  35. # 指定字段
  36. In [16]: print("{name} can be {action}".format(name="strings", action="interpolated"))
  37. strings can be interpolated
  38. # 3.6 新增, 在字符串前加 f
  39. In [62]: f'I love {word}'
  40. Out[62]: 'I love python'
  41. # Python中的字符串可以被索引, 当做只读列表操作
  42. # 赋值和数组越界都会报错
  43. In [18]: word = 'python'
  44. # 截取下标为1的字符
  45. In [19]: print(word[1])
  46. y
  47. # 负数表示从最后开始,-1表示最后一个
  48. In [20]: print(word[-1])
  49. n
  50. # 左包含右不包含
  51. In [21]: print(word[1:4])
  52. yth
  53. # 省略左边表示从0开始
  54. # 省略右边表示到最后结束
  55. In [22]: print(word[:4])
  56. pyth
  57. # 长度, 这个特殊一点
  58. In [32]: len(word)
  59. Out[32]: 6
  60. # 遍历, 也可以像列表那样
  61. In [54]: for i in word:
  62. ...: print(i)
  63. ...:
  64. p
  65. y
  66. t
  67. h
  68. o
  69. n
  70. # 其他都有其方法,可以查看文档
  71. # 正则表达式
  72. import re
  73. # 将正则表达式编译成 Pattern 对象
  74. pa = re.compile(r'\d{1,2,3}')
  75. # match 方法返回一个对象, 只找第一个匹配的
  76. In [51]: g = pa.match('12321')
  77. In [53]: g.group()
  78. Out[53]: '12'
  79. # findall 返回一个列表, 所有匹配的结果
  80. In [50]: pa.findall('12321')
  81. Out[50]: ['12', '32']

3.3 列表

  1. # 定义
  2. >>> squares = [1, 4, 9, 16, 25]
  3. >>> squares
  4. [1, 4, 9, 16, 25]
  5. # 查找
  6. #根据索引找值
  7. >>> squares[0] # indexing returns the item
  8. 1
  9. >>> squares[-1]
  10. 25
  11. >>> squares[-3:] # slicing returns a new list
  12. [9, 16, 25]
  13. # 根据值找索引
  14. In [103]: squares.index(9)
  15. Out[103]: 1
  16. # 新增
  17. # 单个元素
  18. In [65]: squares.append([36, 49])
  19. In [66]: squares
  20. Out[66]: [1, 4, 9, 16, 25, [36, 49]]
  21. # 任意位置, (index, value)
  22. In [113]: stack.insert(0, 6)
  23. # + 号拼接
  24. >>> squares + [36, 49, 64, 81, 100]
  25. [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
  26. # extend 拼接
  27. In [70]: squares.extend([36, 49])
  28. In [71]: squares
  29. Out[71]: [1, 4, 9, 16, 25, 36, 49]
  30. # 修改
  31. # 单个元素
  32. In [73]: squares[0] = 0
  33. In [74]: squares
  34. Out[74]: [0, 4, 9, 16, 25, 36, 49]
  35. # 批量修改
  36. In [75]: squares[:2] = [1, 2]
  37. In [76]: squares
  38. Out[76]: [1, 2, 9, 16, 25, 36, 49]
  39. # 删除
  40. # 根据索引删除
  41. In [68]: squares.pop(-1)
  42. Out[68]: 25
  43. # 使用 del 内置函数删除
  44. In [104]: del(squares[0])
  45. # 根据值删除
  46. In [81]: squares.remove(1)
  47. # 批量删除
  48. In [107]: del(squares[0:2])
  49. # 全部删除
  50. In [96]: squares.clear()
  51. In [96]: del squares[:]
  52. # 甚至可以删除变量
  53. del squares
  54. # 长度
  55. In [83]: len(squares)
  56. Out[83]: 4
  57. # 倒序遍历
  58. # 注意 range 函数也是左包含右不包含
  59. In [99]: for i in range(len(stack)-1, -1, -1):
  60. ...: print(stack[i])
  61. ...:
  62. 5
  63. 4
  64. 3

3.4 字典(键值对)

  1. # 定义
  2. >>> tel = {'jack': 4098, 'sape': 4139}
  3. # 新增
  4. >>> tel['guido'] = 4127
  5. >>> tel
  6. {'jack': 4098, 'sape': 4139, 'guido': 4127}
  7. # 查询
  8. >>> tel['jack']
  9. 4098
  10. # 删除
  11. >>> del tel['sape']
  12. >>> tel['irv'] = 4127
  13. >>> tel
  14. {'jack': 4098, 'guido': 4127, 'irv': 4127}
  15. # 获取键的列表
  16. >>> list(tel)
  17. ['jack', 'guido', 'irv']
  18. # 遍历
  19. In [121]: for i in tel:
  20. ...: print(f'key={i}, value={tel[i]}')
  21. # 同时遍历键和值
  22. >>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
  23. >>> for k,v in knights.items():
  24. ... print(k,"=",v)
  25. ...
  26. gallahad = the pure
  27. robin = the brave
  28. # 将键排序
  29. >>> sorted(tel)
  30. ['guido', 'irv', 'jack']
  31. >>> 'guido' in tel
  32. True
  33. >>> 'jack' not in tel
  34. False

3.5 集合

可以使用大括号 或者 set() 函数创建set集合,创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典

  1. >>> student = {'Tom', 'Jim', 'Mary', 'Tom', 'Jack', 'Rose'}
  2. >>> print(student) # 重复的元素被自动去掉
  3. {'Jim', 'Jack', 'Mary', 'Tom', 'Rose'}
  4. >>> 'Rose' in student # membership testing(成员测试)
  5. True
  6. >>> # set可以进行集合运算
  7. ...
  8. >>> a = set('abracadabra')
  9. >>> b = set('alacazam')
  10. >>> a
  11. {'a', 'b', 'c', 'd', 'r'}
  12. >>> a - b # a和b的差集
  13. {'b', 'd', 'r'}
  14. >>> a | b # a和b的并集
  15. {'l', 'm', 'a', 'b', 'c', 'd', 'z', 'r'}
  16. >>> a & b # a和b的交集
  17. {'a', 'c'}
  18. >>> a ^ b # a和b中不同时存在的元素
  19. {'l', 'm', 'b', 'd', 'z', 'r'}

3.6 栈和队列

  1. # 栈的实现
  2. # 可以通过列表实现
  3. In [84]: stack = [3, 4, 5]
  4. # 入栈
  5. In [85]: stack.append(6)
  6. In [86]: stack
  7. Out[86]: [3, 4, 5, 6]
  8. # 出栈
  9. In [87]: stack.pop()
  10. Out[87]: 6
  11. In [88]: stack
  12. Out[88]: [3, 4, 5]
  13. # 队列的实现
  14. # 也可以通过列表实现, 但是将第一个元素弹出,速度上比较慢
  15. # 推荐使用 collections.deque
  16. >>> from collections import deque
  17. >>> queue = deque(["Eric", "John", "Michael"])
  18. >>> queue.append("Terry") # Terry arrives
  19. >>> queue.append("Graham") # Graham arrives
  20. >>> queue.popleft() # The first to arrive now leaves
  21. 'Eric'
  22. >>> queue.popleft() # The second to arrive now leaves
  23. 'John'
  24. >>> queue # Remaining queue in order of arrival
  25. deque(['Michael', 'Terry', 'Graham'])

3.7 元组

元组是不可变序列, 不能增, 删, 改, 只能遍历
定义, 遍历, 合并, 与列表的相互转换

  1. # 定义
  2. >>> t = 12345, 54321, 'hello!'
  3. # 查询
  4. >>> t[0]
  5. 12345
  6. >>> t
  7. (12345, 54321, 'hello!')
  8. # 遍历
  9. In [135]: for i in t:
  10. ...: print(i)
  11. ...:
  12. 12345
  13. 54321
  14. hello!
  15. # 合并
  16. tup1 = (12, 34.56)
  17. tup2 = ('abc', 'xyz')
  18. tup3 = tup1 + tup2
  19. print (tup3)
  20. # 元组 -> 列表
  21. In [138]: list(t)
  22. Out[138]: [12345, 54321, 'hello!']
  23. # 列表 -> 元组
  24. In [137]: squal = [1, 1]
  25. In [137]: tuple(squal)
  26. Out[137]: (1, 1)

基本数据类型的相互转换都是通过其构造函数

4.练习

4.1 时间

使用 datetime 模块, 用于处理日期和时间
包括 time, date, datetime, timedelta(时间间隔) 等等
更多用法参考文档

  1. from datetime import datetime
  2. # 当前时间对象
  3. now = datetime.now()
  4. # 当前时间戳, 单位: 秒
  5. int(now.timestamp())
  6. 1631193729
  7. # 格式化输出, 年-月-日 时:分:秒
  8. now.strftime('%Y-%m-%d %H:%M:%S')
  9. '2021-09-09 21:22:09'
  10. # 格式化时间转时间戳
  11. ftime = datetime.strptime('2021-09-09 21:22:09', '%Y-%m-%d %H:%M:%S')
  12. int(ftime.timestamp())
  13. 1631193729
  14. # 时间戳转格式化时间
  15. timestemp = datetime.fromtimestamp(1631193729)
  16. timestemp.strftime('%Y-%m-%d %H:%M:%S')
  17. '2021-09-09 21:22:09'

4.2 文件与目录

4.2.1 文件

  1. # 有两种方式: 内置open 和 os.open
  2. # 后者是适用于底层的 I/O。常规用途请使用内置函数 open
  3. # 全部读
  4. file = open("a.txt","r")
  5. file.read('')
  6. file.close()
  7. # 不用close
  8. with open("a.txt", "r") as f:
  9. print(f.read())
  10. # 按行读
  11. for line in open("chapter_4_with.txt", 'r'):
  12. print(line)
  13. # 按行读并获取行号
  14. for line_num, content in enumerate(open(file_path)):
  15. print 'line numbers=%s,content=%s' % (line_num, content)
  16. # 创建文件并写入
  17. with open("a.txt", "w") as f:
  18. f.write('abc')
  19. # 追加写入
  20. with open("a.txt", "a") as f:
  21. f.write('abc')
  22. # 删除文件
  23. import os
  24. os.remove('a.txt')
  25. # 修改文件名
  26. os.rename('a.txt', 'b.txt')
  27. # 文件大小,单位:字节
  28. fsize = os.stat('b.txt')
  29. fsize.st_size
  30. # 替换文件中的字符
  31. # 如果直接写,会覆盖原有内容
  32. # 如果先调用read,再写入,则变为追加,所以要seek(0)
  33. #
  34. with open('a.txt', 'r+') as f:
  35. content = f.read()
  36. c = content.replace('hello', 'bbbb')
  37. print(c)
  38. f.seek(0)
  39. f.write(c)

文件模式:
分两类:文件类型(t、b)与操作类型(r、w、a、x,+)

字符 意义
‘r’ 读取(默认)
‘w’ 写入,并先清空文件
‘x’ 排它性创建,如果文件已存在则失败
‘a’ 写入,如果文件存在则在末尾追加
‘b’ 二进制模式
‘t’ 文本模式(默认)
‘+’ 打开用于更新(读取与写入)
  • 模式 ‘w+’ 与 ‘w+b’ 将打开文件并清空内容。
  • 模式 ‘r+’ 与 ‘r+b’ 将打开文件并清空内容, 即覆盖写入。

    4.2.2 目录

    推荐使用 pathlib 模块— 面向对象的的文件系统路径,原来的 os.path 虽然可以用,不过略显麻烦。
    推荐使用 shutil 模块,提供了一系列对文件和文件集合的高阶操作。特别是提供了一些支持文件拷贝和删除的函数。 ```python In [1]: from pathlib import Path

    初始化当前目录对象

    In [2]: p = Path(‘.’)

    绝对路径

    In [3]: p.absolute() Out[3]: PosixPath(‘/Users/renyangwei/Documents/PythonProject/examples’)

    列出目录中的文件和目录

    In [4]: for i in p.iterdir(): …: print(i) …: turtle_example.py .DS_Store file_ext_example.py b.txt

    拼接路径,可以直接使用 / ,在Windows上会转成 \

    In [7]: ftxt = p / ‘b.txt’ In [9]: ftxt.absolute() Out[9]: PosixPath(‘/Users/renyangwei/Documents/PythonProject/examples/b.txt’)

    也可以使用 joinpath

    In [14]: ftxt.joinpath(‘abc’) Out[14]: PosixPath(‘b.txt/abc’)

文件全名

In [8]: ftxt.name Out[8]: ‘b.txt’

后缀名

In [10]: ftxt.suffix Out[10]: ‘.txt’

不包含后缀的文件名

In [12]: ftxt.stem Out[12]: ‘b’

分离各目录

p = PurePath(‘/usr/bin/python3’) p.parts (‘/‘, ‘usr’, ‘bin’, ‘python3’)

p = PureWindowsPath(‘c:/Program Files/PSF’) p.parts (‘c:\‘, ‘Program Files’, ‘PSF’)

是否存在

In [13]: ftxt.exists() Out[13]: True

pathlib中提供了直接替换文件名,后缀名的方法

with_name,with_stem,with_suffix

p = PureWindowsPath(‘c:/Downloads/pathlib.tar.gz’) p.with_name(‘setup.py’) PureWindowsPath(‘c:/Downloads/setup.py’)

打开文件

In [15]: with ftxt.open() as f: …: f.read()

复制文件

In [30]: import shutil

将文件 src 拷贝到文件或目录 dst

如果是目录则用当前的文件名

In [31]: shutil.copy2(‘b.txt’, ‘c.txt’) Out[31]: ‘c.txt’

删除目录

shutil.rmtree(‘mdir’)

  1. <a name="Sndth"></a>
  2. ### 4.3 加密
  3. Python 中使用 [hashlib](https://docs.python.org/zh-cn/3/library/hashlib.html) 模块,支持多种加密
  4. > 输入字符串对象是不被支持的,因为哈希基于字节而非字符
  5. ```python
  6. import hashlib
  7. # MD5
  8. In [19]: m = hashlib.md5(b'12345')
  9. In [20]: m.hexdigest()
  10. Out[20]: '827ccb0eea8a706c4c34a16891f84e7b'
  11. # sha1
  12. In [21]: m = hashlib.sha1()
  13. # 重复调用相当于单次调用并传入所有参数的拼接结果: m.update(a); m.update(b) 等价于 m.update(a+b)
  14. In [22]: m.update(b'12345')
  15. In [23]: m.hexdigest()
  16. Out[23]: '8cb2237d0679ca88db6464eac60da96345513964'

4.4 异步

使用 asyncio 模块,其实就是Python中的协程。
asyncio 是用来编写 并发 代码的库,使用 async/await 语法。
asyncio 往往是构建 IO 密集型和高层级 结构化 网络代码的最佳选择。
示例

  1. >>> import asyncio
  2. # 定义异步函数,使用 async 关键字
  3. >>> async def main():
  4. ... print('hello')
  5. ... await asyncio.sleep(1)
  6. ... print('world')
  7. # 调用异步函数
  8. >>> asyncio.run(main())
  9. hello
  10. world

并发运行

  1. import asyncio
  2. async def factorial(name, number):
  3. f = 1
  4. for i in range(2, number + 1):
  5. print(f"Task {name}: Compute factorial({number}), currently i={i}...")
  6. await asyncio.sleep(1)
  7. f *= i
  8. print(f"Task {name}: factorial({number}) = {f}")
  9. return f
  10. async def main():
  11. # Schedule three calls *concurrently*:
  12. L = await asyncio.gather(
  13. factorial("A", 2),
  14. factorial("B", 3),
  15. factorial("C", 4),
  16. )
  17. print(L)
  18. asyncio.run(main())
  19. # Expected output:
  20. #
  21. # Task A: Compute factorial(2), currently i=2...
  22. # Task B: Compute factorial(3), currently i=2...
  23. # Task C: Compute factorial(4), currently i=2...
  24. # Task A: factorial(2) = 2
  25. # Task B: Compute factorial(3), currently i=3...
  26. # Task C: Compute factorial(4), currently i=3...
  27. # Task B: factorial(3) = 6
  28. # Task C: Compute factorial(4), currently i=4...
  29. # Task C: factorial(4) = 24
  30. # [2, 6, 24]

4.5 命令行

推荐使用 click 模块,一眼就能看懂,非常方便
安装

  1. pip install click

官网示例

  1. import click
  2. @click.command()
  3. @click.option('--count', default=1, help='Number of greetings.')
  4. @click.option('--name', prompt='Your name',
  5. help='The person to greet.')
  6. def hello(count, name):
  7. """Simple program that greets NAME for a total of COUNT times."""
  8. for x in range(count):
  9. click.echo(f"Hello {name}!")
  10. if __name__ == '__main__':
  11. hello()

运行

  1. $ python hello.py --count=3
  2. Your name: John
  3. Hello John!
  4. Hello John!
  5. Hello John!
  6. $ python hello.py --help
  7. Usage: hello.py [OPTIONS]
  8. Simple program that greets NAME for a total of COUNT times.
  9. Options:
  10. --count INTEGER Number of greetings.
  11. --name TEXT The person to greet.
  12. --help Show this message and exit.

4.6 测试

推荐使用 unittest 模块

  1. import unittest
  2. # 继承unittest.TestCase
  3. class TestStringMethods(unittest.TestCase):
  4. # 以 test_ 名称开头的方法
  5. def test_upper(self):
  6. # 断言
  7. self.assertEqual('foo'.upper(), 'FOO')
  8. def test_isupper(self):
  9. self.assertTrue('FOO'.isupper())
  10. self.assertFalse('Foo'.isupper())
  11. def test_split(self):
  12. s = 'hello world'
  13. self.assertEqual(s.split(), ['hello', 'world'])
  14. # check that s.split fails when the separator is not a string
  15. with self.assertRaises(TypeError):
  16. s.split(2)
  17. if __name__ == '__main__':
  18. # 运行单元测试
  19. unittest.main()

4.7 图片

操作图片推荐使用 pillow

  1. # pip3 install Pillow
  2. from PIL import Image
  3. from PIL import ImageFilter
  4. from PIL import ImageDraw
  5. from PIL import ImageFont
  6. img = Image.open("meinv.jpg")
  7. def convert():
  8. """照片去色"""
  9. img01 = img.convert("L")
  10. img01.save("img01.jpg")
  11. def filter():
  12. """模糊"""
  13. img02 = img.filter(ImageFilter.GaussianBlur(radius=10))
  14. img02.save("img02.jpg")
  15. def rotate():
  16. """旋转"""
  17. img03 = img.rotate(90)
  18. img03.save("img03.jpg")
  19. def transpose():
  20. """翻转"""
  21. img04 = img.transpose(Image.FLIP_LEFT_RIGHT)
  22. img04.save("img04.jpg")
  23. def thumbnail():
  24. """缩略图"""
  25. size = (100, 100)
  26. img05 = img.copy()
  27. img05.thumbnail(size)
  28. img05.save("img05.jpg")
  29. def addText():
  30. img06 = img.copy()
  31. draw = ImageDraw.Draw(img06)
  32. font = ImageFont.truetype(r"~/Library/Fonts/Arimo for Powerline.ttf", size=30)
  33. color = "rgb(255,0,0)"
  34. draw.text((50, 50), "hello", fill=color, font=font)
  35. img06.save("img06.jpg")
  36. if __name__ == '__main__':
  37. # convert()
  38. # filter()
  39. # rotate()
  40. # transpose()
  41. # thumbnail()
  42. addText()

4.8 数据处理

  1. import json
  2. # 对象 -> Json字符
  3. class Student(object):
  4. def __init__(self, name, age, score,reward):
  5. self.name = name
  6. self.age = age
  7. self.score = score
  8. self.reward = reward
  9. s = Student('Bob', 20, 88,["三好学生","优秀团干","最佳辩手"])
  10. print(json.dumps(obj=s.__dict__,ensure_ascii=False))
  11. # Json字符串 -> 对象
  12. class Student(object):
  13. def __init__(self, name, age, score,reward):
  14. self.name = name
  15. self.age = age
  16. self.score = score
  17. self.reward = reward
  18. def dict2student(d):
  19. return Student(d['name'], d['age'], d['score'],d['reward'])
  20. json_str = '{"name": "Bob", "age": 20, "score": 88, "reward": ["三好学生", "优秀团干", "最佳辩手"]}'
  21. student = json.loads(json_str,object_hook=dict2student)
  22. print(type(student))
  23. print(student.name)

xml
推荐使用 xml.etree.ElementTree 模块
示例数据

  1. <?xml version="1.0"?>
  2. <data>
  3. <country name="Liechtenstein">
  4. <rank>1</rank>
  5. <year>2008</year>
  6. <gdppc>141100</gdppc>
  7. <neighbor name="Austria" direction="E"/>
  8. <neighbor name="Switzerland" direction="W"/>
  9. </country>
  10. <country name="Singapore">
  11. <rank>4</rank>
  12. <year>2011</year>
  13. <gdppc>59900</gdppc>
  14. <neighbor name="Malaysia" direction="N"/>
  15. </country>
  16. <country name="Panama">
  17. <rank>68</rank>
  18. <year>2011</year>
  19. <gdppc>13600</gdppc>
  20. <neighbor name="Costa Rica" direction="W"/>
  21. <neighbor name="Colombia" direction="E"/>
  22. </country>
  23. </data>

代码

  1. import xml.etree.ElementTree as ET
  2. # 解析文件,如果是字符串使用 fromstring 方法
  3. tree = ET.parse('country_data.xml')
  4. # 根元素
  5. root = tree.getroot()
  6. # 标签
  7. root.tag
  8. # 属性
  9. root.attrib
  10. # 遍历一级节点
  11. >>> for child in root:
  12. ... print(child.tag, child.attrib)
  13. ...
  14. country {'name': 'Liechtenstein'}
  15. country {'name': 'Singapore'}
  16. country {'name': 'Panama'}
  17. # 遍历所有子树
  18. >>> for neighbor in root.iter('neighbor'):
  19. ... print(neighbor.attrib)
  20. ...
  21. {'name': 'Austria', 'direction': 'E'}
  22. {'name': 'Switzerland', 'direction': 'W'}
  23. {'name': 'Malaysia', 'direction': 'N'}
  24. {'name': 'Costa Rica', 'direction': 'W'}
  25. {'name': 'Colombia', 'direction': 'E'}
  26. # 仅查找当前元素的直接子元素
  27. >>> for country in root.findall('country'):
  28. ... rank = country.find('rank').text
  29. # get 访问属性的值
  30. ... name = country.get('name')
  31. ... print(name, rank)
  32. ...
  33. Liechtenstein 1
  34. Singapore 4
  35. Panama 68
  36. # 增删改
  37. # 使用 Element.text 修改文本字
  38. # 使用 Element.set() 方法添加和修改属性
  39. # 使用 Element.append() 添加新的子元素
  40. # 使用 Element.remove() 删除元素
  41. # 解析带有命名空间的 XML
  42. # 手动为 find() 或 findall() 的 xpath 中的每个标记或属性添加 URI
  43. root = fromstring(xml_text)
  44. for actor in root.findall('{http://people.example.com}actor'):
  45. name = actor.find('{http://people.example.com}name')
  46. print(name.text)
  47. for char in actor.findall('{http://characters.example.com}character'):
  48. print(' |-->', char.text)

4.9 执行系统命令

  1. import os
  2. def excute(cmd):
  3. cmd += " 2>&1"
  4. f = os.popen(cmd,"r")
  5. s = f.read()
  6. ret = f.close()
  7. print("ret=", ret)
  8. if ret != None:
  9. print("err=",s)
  10. else:
  11. print("execute sucess!")

5.项目

本人一般就用来写脚本,爬虫、服务端、游戏、Excel、邮件等等以后等有需要或者学到了再补充。