Skip to content

Latest commit

 

History

History
831 lines (677 loc) · 31.6 KB

Python.md

File metadata and controls

831 lines (677 loc) · 31.6 KB
title date tags categories
Python 基础
2018-12-13 08:00:45 -0800
基础
Python

💠

💠 2024-10-31 19:15:14


Python

Official Site
Doc: Python2 | Doc: Python3

Python初学者(零基础学习Python、Python入门)书籍、视频、资料、社区推荐 参考: Python3的主要应用

Anaconda一站式集成环境

Python 项目工程化开发指南

关于Python2与3的变化

摘自 Python核心编程 第三版 Wesley Chun著

  • print 变为 print()
  • 默认字符的编码是 Unicode
  • 增加单类 类型
  • 更新异常的语法
  • 更新了整数
  • 迭代无处不在

列出所有已安装模块: pydoc pydoc3

基础

运行脚本

  1. python 源文件
  2. 源文件 第一行声明 #!/usr/bin/python 和shell脚本一样的用法, 然后 ./源文件
  • 缩进来表示代码块的嵌套关系
  • 单行注释:# 多行注释: """ """
  • 空行的重要性,代码段之间有空行,Python之禅

基础数据类型

  • 数值类型

    • 整型 (-2^31 ~ 2^31-1) 0b,0,0x 2,8,16 进制
    • 浮点型 1.2e2 13.34e-2
    • 复数 3+4j 0.1-0.5j
  • 布尔型

    • 0 或 0.0 视作 False
    • "" '' 视作 False
    • () [] {} 视作 False
  • 字符串

    • 单引号 双引号: 单行字符串
    • 三引号 多行字符串
  • 空值 None

  • 局部变量:

    • _ 标识变量隐藏
  • 全局变量: 定义在函数外的变量,也称公用变量,函数中 global x 声明引用全局变量x

  • 逻辑运算符

    • and or not
  • 选择:

    • if elif else
  • for 循环:

    • for in while 例如:for i in range(1,10,2): 范围 [1,10) 增量为2
    • pass 语句,当某个子句没有任何操作,,用pass保持程序结构完整性 不影响下一句 不像continue
  • while 循环

    • while True:`` while ‘2’ in nums:`` while num<2:
    • while 列表: 直到列表为空退出循环
    if (b==0) and (a==1) :
        pass
        print("pass")
    else:
        print("Hi")
  1. 优化代码 python -O -m py_compile test.py

代码风格

PEP8 官方建议

  • 一行只写一句
  • 表达式尽量不要省略括号,有助于理解
  • 函数的行数不要超过100行
  • 尽量使用系统函数
  • 尽量使用局部变量,不要使用全局
  • 循环,分支,最好不要超过5层
  • 尽量减少否定的条件语句
  • 对输入的数据进行合法性检查

巨坑: tab和空格不能混用,如果你复制别人的代码是tab,自己敲空格,就会缩进错误!!!!, 天灭tab空格保平安, 要不是kate编辑器显示了tab字符,找半天都不知道错在哪

    优美胜于丑陋(Python 以编写优美的代码为目标)
    明了胜于晦涩(优美的代码应当是明了的,命名规范,风格相似)
    简洁胜于复杂(优美的代码应当是简洁的,不要有复杂的内部实现)
    复杂胜于凌乱(如果复杂不可避免,那代码间也不能有难懂的关系,要保持接口简洁)
    扁平胜于嵌套(优美的代码应当是扁平的,不能有太多的嵌套)
    间隔胜于紧凑(优美的代码有适当的间隔,不要奢望一行代码解决问题)
    可读性很重要(优美的代码是可读的)
    即便假借特例的实用性之名,也不可违背这些规则(这些规则至高无上)
    
    不要包容所有错误,除非你确定需要这样做(精准地捕获异常,不写 except:pass 风格的代码)
    
    当存在多种可能,不要尝试去猜测
    而是尽量找一种,最好是唯一一种明显的解决方案(如果不确定,就用穷举法)
    虽然这并不容易,因为你不是 Python 之父(这里的 Dutch 是指 Guido )
    
    做也许好过不做,但不假思索就动手还不如不做(动手之前要细思量)
    
    如果你无法向人描述你的方案,那肯定不是一个好方案;反之亦然(方案测评标准)
    
    命名空间是一种绝妙的理念,我们应当多加利用(倡导与号召)

序列

序列通用操作(包含:字符串,列表,元组)

  • 索引 从左至右:0,1,2...n 从右至左:-1,-2...-n
  • 切片(截取序列的部分) temp[:] 返回一个副本
    • temp[2:4] 数学中的 [2,4)
    • temp[1:] 1到最后 temp[-3:] [-3,-1]
    • temp[:4] [0,4) temp[:-3] [0,-3]
  • :lista+listb 直接连接
  • :lista*4
  • 判断是否存在in not int
  • len()
  • min() max() sum() 要求元素全是数值

列表 list

  • 元素可包含 字符串,浮点,整型,列表,布尔
  • 操作:
    • 增加 + ,append()/extend()尾部加入元素/列表 insert(index, "") 元素插入到任意位置,其后元素后移
    • 检索 count() in
    • 删除 :del list[2] / remove("apple") /pop(index) index为空指最后一个
    • 永久性排序:sort() a-z sort(reverse=True) z-a 列表全是字符串才可
    • 临时性排序:sorted() 也可以使用上面的参数 列表全是字符串才可
    • 永久性的逆序列表:reverse()
  • 类似数组的操作,例如声明数组:参考博客
    • 原始的定义就是 lists = [1, 2, 4]
    • 若要定义连续列表 lists = range(0, 100) 得到的是range对象不是列表对象
    • 若要定义大小1000全为0列表 lists = [0 for x in range(0, 1000)]
  • 二维数组的定义:
    • 原始: lists = [[1, 2], [3, 4]]
    • 仿造一维的定义: lists = [[0 for x in range(10)] for y in range(10)] 10*10 初始为0的列表
    • 简便但是不可行的方法: lists = [[0]*10]*10 这是个坑, 只是声明了一维数组,然后多次引用, 虽然看起来是二维, 引用数据就会发现是一维

set() 函数, 返回结果则是不重复的元素集合


元组 tuple

  • 元组和列表类似但是元组是创建不可更改的
    • 和列表相比,相同点:按定义的顺序排序,负索引一致,可以使用分片
    • 不同点:元组使用的是(),不能增加删除元素,没有index方法但是有in,可以在字典中作为键,列表不可以
    • 由于具有写保护,代码安全,操作速度略快列表
  • 操作:
    • 访问:和列表一样, 使用索引和分片
    • 连接:+ 连接得到新的元组
    • 删除:del 删除整个元组

字符串 str

  • str() 将对象转化成字符串 (注:Python中不能像Java一样字符串和数值直接+)
  • repr() 注意和str()的区别
  • r"d:\python27\" r前缀表示转义字符看成普通字符
  • 因为Python字符串实现是类似字符数组,temp = "python" temp[0] 结果:p temp.index("p") 结果是:0
  • 操作:
    • index('s') 找到s字符的下标
    • find('s',[start,end]) 找s的下标,只有一个整数参数则是start
    • replace('s','v') 替换
    • count('sd') 计数
    • split('') 正则切分 空参数默认是空格
    • join('') 列表转化成字符串的方法
    • cmp(str1,str2) 比较两个字符串是否相等
    • + 进行拼接 可以拼接字符串 列表
    • a in b 判断a是否在b里存在
    • * 重复序列 例如 print "-"*20 就会输出20个 -
    • b = "www.github.com" c = b.split(".") "#".join(c) 实现了将字符串的 . 换成了#
    • "i am %s %d" % ("python",67) %s %d %f 和C语言一样占位符
      • 新的方式 "i am {0} {1} ..".format(23,"ret")
      • 或者"i am {name} {age} ..".format(age=23,name="ret")
      • 字典方式
    • title() 首字母大写

字符串,列表,元组相互转换:

  • 字符串-列表 : list("python")
  • 字符串-元组 : tuple("python")
  • 列表或元组-字符串 join(obj) 参数是列表或元组类型,其元素只能是字符串类型

字符串编码问题

Python3 的 bytes str 之别

str和bytes的关系

  • 解码 encode("utf-8"): str -> bytes
  • 编码 decode(): bytes -> str
    # coding:utf-8
    unicode_str = unicode('使用',encoding='utf-8')
    print unicode_str.encode('utf-8')
    import codecs
    codecs.open('filename',encoding='utf-8')
  • 因为文件不是UTF8:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb9 in position 2: invalid start byte

字典 dict

  • 通过用空间来换取时间,与列表相比,键的增加不影响查找插入速度,需要占用大量内存

  • 特性:

    • 值是可以是任意的,甚至是字典嵌套
    • 键必须不可变,只能由 数值,字符串,元组,不能用列表
  • 操作:

    • 定义 dict={}
    • 添加 dict['count'] = 1
    • 获取 count = dict['count] 但是如果字典中没有该key, 会抛出异常
    • 获取 get(key) 获取不到返回 None
    • 返回所有key/value keys() values()
    • 转化元组 :items()
      • 可用于遍历 for key,value in dict.items():
    • 删除指定键:del() del dict['name']
    • 删除所有:clear()
    • 删除指定键并返回值 :pop()
    • 合并另一个字典:update()
    • in
  • 嵌套:

    • 字典套列表 {'d':['we','e']}
    • 列表套字典,当成普通类型包含即可
    • 字典套字典

运算符

  • 算术运算符

    • 加减一样,* 乘,不仅可以用于数字,还可以用于字符串 ,/ 除,和Java不一样,整数相除也会得到浮点数
    • // 取整除,得到商的整数部分 ,% 取余数 ,** 幂运算 可以用来开根
  • 关系运算符

    • 都是和Java一致
  • 逻辑运算符

    • and or not
  • 身份运算符

    • is : a is b 就是比较 id(a) id(b) 相同则是返回1
    • is not 比较id 不相同返回1
  • 位运算符

    • << >> 左右移
    • & |按位与或
    • ^ ~ 按位异或 按位翻转
  • 算术运算符优先级 ** / // % +

    • // 取整数部分除法
    • ** 幂运算
  • 转义字符:

    • \a 响铃
    • \b 退格 backspace
    • \000 空
    • \f 换页
    • \ 续行符(行尾)

函数

  • 形参赋值传递方式

    • 按位置 就是直接用看起来和Java一样,但不是按类型和位置,只是位置
    • 按指定名称 调用的时候 create(name='hi')
    • 缺省默认值(参数缺省之后,调用可以不传这个参数,否则必须要传) 声明: def create(name='hi')
    • 列表类型,不想形参改变实参 传递副本过去即可 list[:]
  • 多个实参 create(age, *name) create(12, 's','d')

    • 所以这是名为name的元组 不能指定没有的名称 错误:create(12,d=2, 2,3,4)
  • 多个指定名称实参 create(age, **name) create(12, name='d', lo=23)

    • 必须要指定名称 这是名为name的键值对字典
    • 错误:create(12,d=23,3,3,3)
  • 注意:

    • def hi(name, age=0, *names, **s) hi('d', 23,34, d=6) age会被赋值23
    • def hi(name, *names, age=0, **s) hi('d', 23,34, d=6) 这样写age就不会赋值,除非指定名称 age=23
    • 以上两种情况(* 和 **),都必须放在形参列表的最后 (两者同时使用时:* 只能在 ** 前 )
  • 返回值

    • 返不返回 看需求 没有像Java一样的强制性约束类型
  • 将函数写在一个py文件里,然后导入 import 文件名,名曰导入模块

    • 还可以加别名 import creat as fun 给模块加别名
    • 导入指定的函数 from create import create_aliens, type_button 多个就,分隔 同理 as给函数加别名 * 通配所有
  • 注意:递归深度,Python中递归默认深度是 989, 要么更改实现,要么就 sys.setrecursionlimit(10000000)

参考: Magic Method __xxx__ 方法

内置函数

  • id() 查看内存地址
  • help(方法名) 展示方法的说明文档
  • dir(对象) 展示对象的方法API

official tutorial

When importing the package, Python searches through the directories on sys.path looking for the package subdirectory.

  1. 注意不能出现 import 循环依赖 A.py import B.py then B.py import A.py

Python 不存在多态,存在鸭子类型 博客介绍 | python中的多态与鸭子类型

  • 写在一个py文件里,默认构造器,可以加参数 def __init__(self):

  • 属性:

    • 实例属性 形如self.name,在任何方法中声明过即可
    • 类属性 不加self前缀,__name私有的类属性, 类不能访问对象属性
    • 类属性可以修改,但是实际上只能修改实例属性(这个修改只是声明了同名的实例属性,引用的时候就会覆盖类属性,看起来就是修改了
      • 可以删除实例属性,然后就能看到原有的类属性了
    class People:
        name = 'md'
    p = People()
    p.name = 'gh' # 声明了实例属性覆盖了类属性
    del p.name # 删除实例属性,恢复类属性引用
  • 方法:

    • 对象方法,类方法,静态方法
    • 对象方法,同样的 __开头是私有的,只能在对象的公有方法中self.__引用
    • 静态方法,之中只能引用类成员,不能访问对象成员
  • 构造函数和析构函数:

    • def __init__(self)
    • def __del__(self)
    class Person:
        # 对象方法, 将对象作为参数self传进去
        def say(self):
            print('hi')
        # 静态方法
        @staticmethod
        def drink():
            print('static method')
        # 类方法,将类作为参数cls传进去
        @classmethod
        def eat(cls):
            print('class method')
  • self 代表了自身引用 类似Java的this

  • 特别不舒服 init 这种命名 不像Java的构造函数重载,这个就是后面覆盖前面定义的__init__ 不管形参列表

    • 因为不存在重载,就是说不能多个构造函数的书写了。。。
  • 导入和函数一样 注意继承中类的依赖

继承

  • Python是支持多重继承的

  • 同文件 父类定义要在子类之前

  • 父类的构造器不会自动调用,需要显式使用父类构造器:

    • 2.×版本: super(子类名, self).__init__(参数)
    • 3.×版本: super().__init__(参数)
    • 或者 父类名.__init__()
  • 重写父类方法:只需要定义一个和父类方法同名的方法即可,因为没有多态,覆盖时形参不作考虑

  • 多态:

    • 方法重载: 子类覆盖父类的方法
    • 运算符重载: 加__add__(self, x)__sub__(self, x)

异常

    try:
        print(5/0)
    except ZeroDivisionError as err:
        print("0 不能做除数", err)
    else:
        print("成功")
    finally:
        print('finally')
  • 基本语法 try except else finally

    • else 是无异常时执行
    • 有异常就会执行 except, 可以多个except (和Java一致)
      • except Exception as e: 捕获所有异常
    • 最终执行 finally 和 Java的结构是一致的
    except 分句使用形式 说明
    except 捕获所有类型
    except name 只捕获指定类型
    except name, value 捕获指定类型,并获得抛出的异常对象
    except (name1, name2) 捕获列出的异常
    except (name1, name2), value 捕获列出的异常,获得抛出的异常对象
  • raise 语句 和Java的throw关键字 一致 , 不过raise只是抛出一个通用异常类型 Exception

  • dir(exceptions) 查看所有异常类型

    • raise name 手动引发异常
    • raise name,data 传递一个附加的数据
  • 同样的也是可以自定义异常类型的,class MyExcetion(Exception):

  • with 语句 在异常处理中,将 try except finally 关键字以及与资源分配释放相关的代码省略掉。

    • 文件打开 with open('a.py') as files:
常见异常类 描述
NameError/UnboundLocalError 引用不存在的变量/或者引用在声明之前
ZeroDivisionError 除数为0
SyntaxError 语法错误
IndexError 索引错误
KeyError 使用不存在的字典关键字
IOError 输入输出错误
ValueError 搜索列表中不存在的值
AtrributeError 调用不存在的方法
TypeError 未强制转换就混用数据类型
EOPError 文件结束标识错误

读取命令行参数

参考博客

只有输入参数,没有选项

    import sys
    print("脚本名:", sys.argv[0])
    for i in range(1, len(sys.argv)):
        print("参数", i, sys.argv[i])

python tree.py hi op 顺序是python,第一个参数是文件,之后才是别的参数 结果>> 脚本名 tree.py 参数1 hi 参数2 op

有选项 getopt.getopt(args, options[, long_options])

    import sys, getopt
    opts, args = getopt.getopt(sys.argv[1:], "hi:o:")
    for op, value in opts:
    
  • sys.argv[1:]为要处理的参数列表,sys.argv[0]为脚本名,所以用sys.argv[1:]过滤掉脚本名。
  • "hi:o:": 当一个选项只是表示开关状态时,即后面不带附加参数时,在分析串中写入选项字符。当选项后面是带一个附加参数时,在分析串中写入选项字符同时后面加一个":"号。
    • 所以"hi:o:"就表示"h"是一个开关选项(单单的-h);"i:"和"o:"则表示后面应该带一个参数。
  • 调用getopt函数。函数返回两个列表:opts和args。opts为分析出的格式信息。args为不属于格式信息的剩余的命令行参数。
    • opts是一个两元组的列表。每个元素为:(选项串,附加参数)。如果没有附加参数则为空串''。
    • getopt函数的第三个参数[, long_options]为可选的长选项参数,上面例子中的都为短选项(如-i -o)
  • 长选项格式举例:
    • --version
    • --file=error.txt
  • 让一个脚本同时支持短选项和长选项 getopt.getopt(sys.argv[1:], "hi:o:", ["version", "file="])

docopt

Github地址 | 在脚本头部添加文档来实现读取参数的便捷 会读取输入返回字典对象,可以很方便的读取输入的参数,但是需要书写大量文档, 适合参数比较多的时候,一眼过去简洁明了

Python Fire

Github地址快速的简洁的生成CLI 不过要自己书写帮助文档输出,小量参数的话,开发十分的便利 可以和类一起,也可以和方法一起

    import fire
    def main(action=None):
        print(action)
        if action == '-h':
            show_help()
        
    fire.Fire(main)
    # 使用时 py filename.py -h  

应用

模块

python -m module_name

http

  • 快速启动一个 HTTP Web 服务器 http.server [port]

virtualenv

廖雪峰 virtualenv

虽然也可以用apt安装 python-venv, 但是最好不要这样,避免后续模块升级后不必要的冲突

  • 创建环境 python3 -m venv web 或者 virtualenv --no-site-packages web 不将系统中安装的包带入该环境
  • 启动环境 source web/bin/activate
    • 在环境中使用的pip python 都是环境中的, 其实就是修改了系统的环境变量指向
  • 停用环境 deactivate

pip

pip | doc | guide

  1. 作为Python的包管理器, 包的可执行文件默认在 /usr/local/bin 目录下(全局)
    • 如果安装时加了该参数 --user 就是安装在 ~/.local/bin 目录下

install

  • pip install name 安装最新版本
  • pip install name==version 安装指定版本
  • 镜像源 豆瓣 -i https://pypi.doubanio.com/simple/ 清华 -i https://pypi.tuna.tsinghua.edu.cn/simple
  • 代理 --proxy 192.168.1.24:1234
  • 强行使用HTTP -i http://pypi.doubanio.com/simple/ --trusted-host pypi.doubanio.com pip版本高于20.3后默认使用HTTPS
  • 安装tar.gz: pip install xxxx.tar.gz

注意:自PEP668开始限制默认安装为全局依赖,否则会报错 externally-managed-environment

  • 可以设置默认全局 python3 -m pip config set global.break-system-packages true
  • 或者单次安装到全局 --break-system-packages

3.10 后 pip 作为子模块

  • 安装 python -m ensurepip --upgrade
  • 使用 python -m pip install pkgName
  • 升级 python -m pip install --upgrade pip

Requirements files

pip官方文档 Requirements files

  1. 导出 pip freeze > requirements.txt 这个命令会将当前环境安装的包全部列出来, 适合env环境下使用

    • 如果没有使用虚拟环境, 然后只想导出某项目的依赖 Github pipreqs
    • 安装 : pip install pipreqs 然后 pipreqs /path/to/project
  2. 使用 pip install -r requirements.txt

发布包到 pypi

Official : about package

  1. edit $HOME/.pypirc to save authorization info
        [pypi]
        username = <username>
        password = <password>
    
  2. pip3 install wheel twine
  3. rm -rf dist build *.egg-info
  4. python3 setup.py bdist_wheel
  5. twine upload dist/*

可以参考该项目: 终端内使用百度翻译

由于Readme 使用的是 reStructuredText 语法(要求严格,所以需要借助工具)

  1. pip install collective.checkdocs Pygments
  2. python3 setup.py checkdocs

matplotlib


文件操作

  • 注意路径,Windows系统中要使用反斜杠 \

  • 最简单:file = open('') 只读打开

  • 使用with来操作 好处是Python自动关闭文件 类似于Java的TWR

        with open('filename') as file: 
            lines = file.readlines()
  • 为写打开新文本文件只读 file = open('a.txt','w+'[,coding='utf-8']) 打开删空

  • file.write('')

  • os模块

    • os.rename('filename1','filename2') mv
    • os.remove('filename.py') rm
    • os.listdir(path) ls
    • os.getcwd() pwd
    • os.makedirs(r'path') mkdir
    • os.chdir('') 改变一个目录
    • os.rmdir('') 删除该目录,前提是空目录
  • os.path模块

    • abspath('') 获取绝对路径
    • exists('') 是否存在
    • isdir('') 是否是一个目录
    • isfile('') 是否是文件
    • islink('') 是否是软链接硬链接文件
    • getsize() 获取文件尺寸
  • shutil模块

    • dir() 复制单个文件
    • shultil.copytree(r'',r'') 复制目录树
    # 读取大文件
    for line in fileinput.input("test.txt"):
        print(line)

b 表示字节流(二进制文件) 不加表示字符流(文本文件)

字符流方式 意义 当存在 当不存在
r 只读打开 打开 返回空指针
w 只写打开 打开删空 新建打开
a 追加打开 打开 新建打开
r+ 读打开可写 打开 返回空指针
w+ 写打开可读 打开删空 新建打开
a+ 追加打开可读 打开 新建打开

字节流方式 意义 当存在 当不存在
rb 只读打开 打开 返回空指针
wb 只写打开 打开删空 新建打开
ab 追加打开 打开 新建打开
rb+ 读打开可写 打开 返回空指针
wb+ 写打开可读 打开删空 新建打开
ab+ 追加打开可读 打开 新建打开

JSON

    import json
    file_name='result.json'
    
    def write_json():
        global file_name
        person = {'color': 'green', 'age': '23'}
        with open(file_name, 'w') as o:
            json.dump(person, o)

    def read_json():
        global file_name
        with open(file_name) as file:
            datas = json.load(file)
            for data in datas :
                # 引用的时候就当做是字典
                print(data, datas[data])

conf或者ini

参考: python操作ini文件

    import os
    from configparser import ConfigParser

    path = os.path.split(os.path.realpath(__file__))[0]
    mainConf = path + '/main.conf'
    cf = ConfigParser()
    cf.read(mainConf)
    host = cf.get('redis', 'host')

    # 写 但是要有write节点
    cf.set('write', 'add', '12')
    cf.write(open(mainConf, 'r+'))

对应的conf

    [redis]
    host=127.0.0.1

日志

logging

    # 标准输出
    LOG_FORMAT = "%(asctime)s.%(msecs)03d %(levelname)s %(message)s"
    DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
    logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT, datefmt=DATE_FORMAT)
    log = logging.getLogger()

    # 文件和标准输出
    LOG_FORMAT = "%(asctime)s.%(msecs)03d %(levelname)s %(message)s"
    DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
    logging.basicConfig(filename='run.log', level=logging.DEBUG, format=LOG_FORMAT, datefmt=DATE_FORMAT)

    log = logging.getLogger()
    stdout_handler = logging.StreamHandler(sys.stdout)
    rowFmt = logging.Formatter(fmt=LOG_FORMAT, datefmt=DATE_FORMAT)
    stdout_handler.setFormatter(rowFmt)
    log.addHandler(stdout_handler)

    # Pycharm 跳转 类似Java IDEA的 (xxx.java:100) 特定格式 logback配置 \\(%F:%line\\)
    LOG_FORMAT = "%(asctime)s.%(msecs)03d %(levelname)s File \"%(filename)s\", line %(lineno)s %(funcName)s  %(message)s"

    LOG_FORMAT = "%(asctime)s.%(msecs)03d %(levelname)s %(filename)s:%(lineno)s %(funcName)s  %(message)s"

Python之日志处理(logging模块) - 云游道士 - 博客园

loguru

Effective Logging in Threaded or Multiprocessing Python Applications

但是 FastApi 里的 BackgroundTasks 是跨线程的,但是同样支持log, 需要找找怎么实现的

  • 实际上是因为他是协程,不是线程

测试

  • 文件名test_开头, 需要 unittest.main() 方式运行
  • 类继承 unittest.TestCase, 所有test_开头的方法都将自动运行
  • 断言 self.assertEqual assertNotEquals assertIn(item, list)
  • 输出结果: . 测试通过 E 测试运行错误 F 测试断言不通过

数据库

MySQL

pip install mysqlclient

  • import MySQLdb

Redis

安装模块

  • python2 sudo pip install redis
  • python3 sudo pip3 install redis

使用

部署

Docker部署

参考官方文档

    FROM python:3
    WORKDIR /usr/src/app
    COPY requirements.txt ./
    RUN pip install --no-cache-dir -r requirements.txt
    COPY . .
    CMD [ "python", "./your-daemon-or-script.py" ]
    FROM python:2
    WORKDIR /usr/src/app
    COPY requirements.txt ./
    RUN pip install --no-cache-dir -r requirements.txt
    COPY . .
    CMD [ "python", "./your-daemon-or-script.py" ]
  • You can then build and run the Docker image:
    • $ docker build -t my-python-app .
    • $ docker run -it --rm --name my-running-app my-python-app

常见库

内置库

  • codecs 编码

  • os 操作系统相关API

    • 获取脚本绝对路径 os.path.split(os.path.realpath(__file__))[0]
    • 获取用户目录 os.environ['HOME'] | os.path.expandvars('$HOME') | os.path.expanduser('~')
  • platform 操作系统信息

    • 获取当前操作系统名称 platform.system()
  • subprocess 代码

时间处理

time

菜鸟教程: Python 日期和时间

  1. 格式化当前时间 time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

三方库

  • qrcode 终端生成二维码
  • redis 和Redis命令完美融合
  • httpie HTTP方便的交互 doc
    • POST时 特别注意:参数==值
  • python-excel
  • python-docx 文档
  • chef 文档 Use the python resource to execute scripts using the Python interpreter