python基础
- 建议编码风格
- 使用制表符或4个空格缩进代码块,为了各平台的兼容性制表和空格不要混用。
- 类与类之间用2行空格分隔。
- 用空行分隔函数和类,以及函数内较大的代码块。
- 使用文档字符串,给类,函数,方法等添加说明。
- 在运算符前后和逗号后面使用空格,更易于阅读。
- 使用驼峰命名类: UpperCamelCase。
- 使用下划线和小写字符命名函数和方法:lowercase_with_underscores 。
- 变量名
变量由大、小写字母,字符,数字和下划线组成。(数字不能放在首位,跟C语言一样)
- 关键字
关键字又名保留字,不可被用作普通标识符。python 3.7.4的所有35个关键字如下:
关键字 | 描述 | 关键字 | 描述 |
return | 退出函数,还可返回值。 | is | is 用于比较两个对象是否相等,==仅仅比较内容是否相等,is不但比较内容,还比较地址是否相等。 |
yield | 生成器 | break | 退出循环 |
def | 定义函数 | while | while 循环 |
del | 删除对象引用 | for | for 循环 |
False | 逻辑假 | in | 用于成员检测: x in la |
True | 逻辑真 | continue | 结束当前循环,继续下一循环 |
None | 空值 | with | 上下文管理器 |
import | 导包语句。例子:from A import B | as | 起一个别名。用在导包,上下文管理with及异常处理中。 |
from | 用于导包语句中 | try | 异常: 捕获异常关键字 |
pass | 空语句,用于占位 | except | 异常:处理异常关键字 |
raise | 显示抛出异常 | finally | 异常:清理工作关键字 |
class | 定义类 | global | 用于什么变量为全部变量 |
if | 条件判断 if | nonlocal | 用于闭包函数中,什么变量为外层函数定义的变量。 |
elif | 条件判断 elif | lambda | 用于创建匿名函数 |
else | 条件判断 else | await | 协程相关 |
or | 逻辑或 | async | 协程相关 |
and | 逻辑与 | assert | 断言语句 |
not | 逻辑非 |
- 保留标识符
某些以下划线开头和结尾的标识符具有特殊含义。
_*,模块中定义的以下划线开头的函数不能被 `from module import *`导入。(*代表除下划线外的其他标识符,下同)
__*__,系统定义的名称,自定义标识符最好不要用这样的方式,以免发生意外错误。
__*,类的私有名称(非严格私有,只是做了隐蔽处理。)。
- 赋值
python中赋值均为对象的引用赋值。
- 模块
模块是python代码的基本组织单元。模块属性__dict__返回模块符号表的字典。
通常将一个python程序拆分成多个文件(以.py为后缀名),一个文件就是一个模块,文件名就是模块名,模块主要包含的内容:
-
- import导入语句 -- 用于导入本模块需要用到的其他模块的功能。
- 函数定义。
- 类的定义。
- 全局变量 -- 在函数和类外定义。表示模块范围内的全局变量。
- 可执行的函数语句 -- 语句位于类和函数定义外面。在被外部导入时执行,用于初始化模块。
模块的使用:
模块中的__name__系统变量指示模块被加载或执行。
如果模块是被导入,__name__的值为模块名字。
如果模块是被执行,__name__的值为'__main__'。
-
- 以脚本的方式运行
# 导入外部模块 # 定义全局变量 # 函数定义 # 类定义 # 定义脚本方式单模块运行的代码 if __name__ == '__main__' # 执行代码 # ... pass
-
- 被其他模块通过import语句导入
- 包
- 一个包的基本组成:
tools
__init__.py
math.py
str.py
建立文件夹tools,在里面创建一个__init__.py文件,可以为空。
然后将math.py和str.py添加进来。
包就是用文件夹的形式管理python文件(或者模块)。
-
- 包的导入
假如工程目录如下:
project
tools
__init__.py
math.py
str.py
main.py
-
-
- main.py中导入math模块:
-
import tools.math
或者:
import tools.math as my_math
或者:
from toos import math
或者:
from toos import math as my_math
-
-
- 直接导入函数名或变量
-
import from tools.math import my_abs
调用:my_abs(-12)
-
- 从包中导入所有
from module import *
如果被导入包的__init__.py文件存在__all__列表:__all__ = ["echo", "surround", "reverse"]
则只能导入列表中的内容。
-
- 相对导入
从当前目录导入math包
from . import math
从上一级目录导入math包
from .. import math
从上上一级tools目录中导入math包
from ..tools import math包
- 数值类型
- 整数
整数分为整型和布尔型,布尔型逻辑值为True和False。True和False的值分别为1和0。整数位数没有大小限制。
整数的表示:
十进制
由以非0开头其他位为0-9的数字组成: 100, 50000, 999
十六进制
以0x或者0X开头,由0-9的数字或者A-F的字符组成: 0x23, 0XF1A1
八进制
以0o或者0O开头, 由0-7的数字组成: 0o20, 0O1123
二进制
以0b或者0B开头,由0-1数字组成: 0b10, 0B1101101
可以在数值中加入下划线提高可读性。例如:
0x_3F09, 0B_1000_0010_0001, 0O_1707
-
- 浮点数
为了语言的简洁性python不支持单精度浮点数,默认都为双精度浮点数。
浮点数分为小数表示形式和指数表示形式:
小数形式:
0.586, .124, 80.25
指数形式:
1.5e2, 1.5e-2, -1.5e2
整数部分支持下划线分组:
8_0.25的数值大小仍然为80.25.
整数部分都是10进制数,整数前面可以有0。
080.25的值大小也是80.25
-
- 复数
同样用双精度表示复数值,一个复数值z的实部和虚部通过只读属性z.real和z.imag来获取。
- 数值的进制转换
print(bin(17)) print(hex(17)) print(oct(17)) # 输出: 0b10001 0x11 0o21
- 不可变序列
- 字符串
内置函数ord()和chr()可以在字符和数字之间转换。
str.encode()和bytes.decode()实现字符串和bytes之间的转换。
- 元组
元组可以包含任意python对象,对象之间由逗号分隔。
- 字节串
字节串是不可变数组。
- 可变序列
- 列表
列表条目可以是任何python对象,列表由方括号括起来并由逗号分隔。
-
- 字节数组
字节数组属于可变数组,通过内置bytearray()构造器来创建。
- 集合类型
集合由花括号包含,元素不重复且元素之间由逗号分隔,可迭代,可用内置函数len()返回条目数。
集合应用场景:去除序列中的重复项目,快速成员检测。
-
- 可变集合
可变集合通过内置set()构建,创建之后通过add()添加元素。另外可以直接通过花括号创建集合:{1, 2, 3},但是空集合只能用set()创建。
-
- 冻结集合
通过内置frozenset()创建,为不可变集合。由于冻结集合对象不可变,他可以被用作另一个集合的元素和字典的键。
- 字典
由键值对组成的集合。
- 行结构
一行 Python 程序可由一行或多行物理行拼接。行拼接分显示拼接和隐式拼接2中:
# 显示拼接 if 1900 < year < 2100 and 1 <= month <= 12 \ and 1 <= day <= 31 and 0 <= hour < 24 \ and 0 <= minute < 60 and 0 <= second < 60: # Looks like a valid date return 1 # 隐式拼接 month_names = ['Januari', 'Februari', 'Maart', # These are the 'April', 'Mei', 'Juni', # Dutch names 'Juli', 'Augustus', 'September', # for the months 'Oktober', 'November', 'December'] # of the year
注意:以反斜杠拼接的行后面不能有#开始的注释,隐式的行拼接可以带有注释。
- 注释
代码注释以#开头(包含在字符串里面的#当做普通字符)。
文档注释以3个双引号开始和结束"""文档描述"""。
- 编码声明
格式如: # -*- coding: utf-8 -*-
或者: # coding: utf-8
在python3中如果没有编码声明,则默认编码为 UTF-8。
- 代码缩进
通常为4个空格或一个tab,同一代代码块保持相同的缩进。
- 字符串
- 字符串的表示
用单引号、双引号或三引号(成对3个连续单引号和成对3个连续双引号)表示字符串,如: 'abd'、"abc"、"""abc"""或者'''abc'''
在一个字符串中可以混合使用这3种表示方式,但引号的开始与结束必须具有相同类型。
示例如下:
print('一对单引号:', 'hello python haha') print('一对双引号:', "hello python haha") print('一对三引号--成对连续3个双引号:', """hello python haha""") print('一对三引号--成对连续3个单引号:', '''hello python haha''') print('一对单引号里面包括双引号:', '"hello" "python" haha') print('一对双引号里面包括单引号:', "'hello' 'python' haha") print('一对三引号(成对连续3个双引号)里面包括单、双引号:', """'hello' "python" haha""") print('一对三引号(成对连续3个单引号)里面包括单、双引号:', ''''hello' "python" haha''') # 输出: 一对单引号: hello python haha 一对双引号: hello python haha 一对三引号--成对连续3个双引号: hello python haha 一对三引号--成对连续3个单引号: hello python haha 一对单引号里面包括双引号: "hello" "python" haha 一对双引号里面包括单引号: 'hello' 'python' haha 一对三引号(成对连续3个双引号)里面包括单、双引号: 'hello' "python" haha 一对三引号(成对连续3个单引号)里面包括单、双引号: 'hello' "python" haha
-
- 字符串中的常用转义字符
转义字符 | 意义 | 注释 |
'\\' | 反斜杠(\) | |
'\'' | 单引号(') | |
'\''' | 双引号(") | |
'\n' | 换行 | |
'\r' | 回车 | |
'\t' | 水平制表 | |
'\v' | 垂直制表 | |
'\ooo' | ooo代表1-3位8进制数 | |
'\xhh' | hh代表2位16进制数 | |
'\N{name}' | Unicode 数据库中名称为 name 的字符: http://www.unicode.org/Public/11.0.0/ucd/NameAliases.txt | 仅用于字符串中 |
'\uxxxx' | 16位十六进制数 xxxx 码位的字符 | 仅用于字符串中 |
'\Uxxxxxxxx' | 32位16进制数 xxxxxxxx 码位的字符 | 仅用于字符串中 |
-
- 字符串前缀
- f或F前缀
- 字符串前缀
字符串中用{}包含替换字段,实现字符串格式化。字符串中{}中的内容被替换,{}中的内容不允许有反斜杠。
花括号中!表示转换字段,
!s
即对结果调用str(),
!r
为调用repr(),
而 !a
为调用ascii()
lang = 'python' print(f'hello world {lang}') print(f'hello world {{lang}}') print(f'hello world {lang!s}') print(f'hello world {lang!r}') print(f'hello world {lang!a}') # 输出: hello world python hello world {lang} hello world python hello world 'python' hello world 'python'
-
-
- 前缀为u或者U
-
u'hello python!' , 表示字符串以Unicode字符存储。
-
-
- 前缀为r或者R
-
r'hello \n python', \字符不转义,原样输出: hello \n python
ver = '3.7.4' print(FR'不转义\\,且格式化字符串python version={ver}') print(Fr'不转义\\,且格式化字符串python version={ver}') print(fR'不转义\\,且格式化字符串python version={ver}') print(fr'不转义\\,且格式化字符串python version={ver}') # 输出: 不转义\\,且格式化字符串python version=3.7.4 不转义\\,且格式化字符串python version=3.7.4 不转义\\,且格式化字符串python version=3.7.4 不转义\\,且格式化字符串python version=3.7.4 # 以上输出都是一样的!
-
-
- 前缀为b或者B
-
字符串前缀为b或者B生成bytes类型而非str类型。ASCII字符之外的字符用转义形式表示。
print(b'python \x7e\x89') # 输出: b'python ~\x89'
- 字符串拼接
多个字符串用加号拼接,也有自动拼接的情况。
# ‘+’ 拼接 str1 = 'hello python ' + "haha" str2 = 'hello python ' + 'haha' str3 = 'hello python ' + """haha""" print(str1) print(str2) print(str3) #自动拼接 print('a' 'good' 'man') # 输出: hello python haha hello python haha hello python haha agoodman
- 运算符
- 算数运算符
运算符 | 说明 | 例子 |
+ | 加 | 1+1=2 |
- | 减 | 1-1=0 |
* | 乘 | 1*1=1 |
** | 乘方 |
2**3=8 2**4=16 |
/ | 除(取到小数位) | 20.4/4=5.1 |
// | 除(向下取整) |
9.3//2=4 -9.3//2=-5 |
% | 取模 |
9%2=1 9.3%2=1.3 |
-
- 比较运算符
运算符 | 说明 | 例子 |
== | 等于 | |
!= | 不等于 | |
<> | 不等于(python3.7已废除,用!=替代) | |
> | 大于 | |
>= | 大于等于 | |
< | 小于 | |
<= | 小于等于 |
-
- 赋值运算符
运算符 | 说明 | 例子 |
= | 基本赋值运算符 | a=2 |
+= | 加法赋值 | |
-= | 减法赋值 | |
*= | 乘法赋值 | |
/= | 除法赋值 | |
%= | 取模赋值 | |
//= | 整除赋值 | |
**= | 乘方赋值 |
-
- 位运算符
运算符 | 说明 | 例子 |
& | 按位与 | |
| | 按位或 | |
^ | 按位异或 | |
~ | 按位取反 | |
<< | 左右 | |
>> | 右移 |
-
- 逻辑运算符
运算符 | 说明 | 例子 |
and | 逻辑与 | |
or | 逻辑或 | |
not | 逻辑非 |
-
- 成员运算符
运算符 | 说明 | 例子 |
in | 判断元素是否在序列中 | x in y |
not in | 判断元素是否不在序列中 | x not in y |
-
- 身份运算符
运算符 | 说明 | 例子 |
is | 判断两标识符是否引自同一个对象 | a is b(类似id(a)==id(b)) |
is not | 判断两标识符是否引自不同对象 | a is not b |
-
- 其他运算符
运算符@用在装饰器。
- 算数转换
- 如果任一参数为复数,或者浮点数,另一参数也会被相应转换为复数、浮点数。
- 运算符的优先级
优先级(python3.7.4) | 运算符 | 说明 |
1(最高优先级) | (1,2,3, ...), [4,5,6, ...], {'a'=1, 'b'=2, ...}, {1, 2, 3, ... } | 元组、列表、字典、集合 |
2 | x[index], x[index1: index2], x(arguments...), x.attribute | 抽取,切片,调用,属性引用 |
3 | await x | await表达式 |
4 | ** | 乘方(例外: 负数作为乘方的指数时 2**-1 = 0.5) |
5 | ~, +, - | 按位取反,正号,负号 |
6 | *, %, /, //, @ | 乘, 取模,除, 整除, 矩阵乘 |
7 | +, - | 加法,减法 |
8 | <<, >> | 左移,右移 |
9 | & | 按位与 |
10 | ^ | 按位异或 |
11 | | | 按位或 |
12 | in, not in, is, is not, >, >=, <, <=, ==, != | 比较运算,成员检测,身份检测 |
13 | not x | 布尔运算: 逻辑非 |
14 | and | 布尔运算: 逻辑与 |
15 | or | 布尔运算: 逻辑或 |
16 | if else | 条件表达式 |
17(最低优先级) | lambda | lambda表达式 |
- 实例:
# not, and, or的优先级 print(not False and False) print(False and False or True) # 输出: False True # 在编程是,可以用一对小括号人为指定优先级。这样的代码更易于阅读。 print(not (False and False)) # 输出: True
- 其他符号说明
符号 | 说明 | 例子 |
, | 逗号 | |
: | 冒号 | |
. | 点号 | |
'' | 单引号 | |
"" | 双引号 | |
# | 注释符号 | |
\ | 续行符号 |
- 简单语句
- 赋值语句
赋值语句用于将名称(重)绑定到特定值,以及修改属性和可变对象的成员项。如: x=3
-
- 增强赋值语句
+=, *=, %=等语句。
-
- assert 语句
assert语句用于在程序中方便地插入调试性断言。
a = 10 assert a > 10, '数据不满足要求!' # 结果: assert a > 10, '数据不满足要求!' AssertionError: 数据不满足要求!
-
- pass 语句
pass是一个空操作,用于临时占位。
-
- del 语句
a = 100 b = a c = b del a del b print(c) # 输出结果: 100 a = [12, 23, 55, 78] del a[1] print(a) # 输出结果: [12, 55, 78]
-
- return 语句
用于函数返回,以表达式、列表或None作为返回值。
-
- yield 语句
在定义生成器函数时使用。
-
- raise 语句
引发自定义异常
-
- break 语句
break出现于for和while循环中,跳出最近一层的循环。
-
- continue 语句
continue语句也只出现于for和while循环中,结束当前循环,继续当前循环层的下一轮循环。
-
- import 语句
用于从其他模块导入符号。
-
- future 语句
- global 语句
- nonlocal 语句
# global 和 nonlocal演示 a = 100 b = 200 def func(): global a b = 300 a = 101 print(f'func a= {a}, id={id(a)}') def sub(): nonlocal b b = 301 print(f'sub b={b}, id={id(b)}') sub() def main(): print('func调用前:') print(f'main a= {a}, id={id(a)}') print(f'main b= {b}, id={id(b)}') print('调用func') func() print('func调用后:') print(f'main a= {a}, id={id(a)}') print(f'main b= {b}, id={id(b)}') # 结果: func调用前: main a= 100, id=140734467341152 main b= 200, id=140734467344352 调用func func a= 101, id=140734467341184 sub b=301, id=1912489332432 func调用后: main a= 101, id=140734467341184 main b= 200, id=140734467344352
- 复合语句
- if 语句
a = 5 b = 7 if a > b: print('big') elif a == b: print('equ') else: print('small') # 结果: small
-
- while 语句
while 语句用于在条件表达式为真时重复执行。
-
- for 语句
for 语句用于对序列和可迭代对象中的元素进行迭代。
-
- try 语句
try语句用于捕获异常。
# 捕获异常 try: a = 125/0 except Exception as e: print(e) finally: print('处理finally') # 输出: division by zero 处理finally
-
- with 语句
普通函数实现 __enter__ 和 __exit__ 函数就可以被上下文管理器语句with管理。或者方法添加装饰器: @contextlib.contextmanager
# 方法1: 实现enter和exit class MyContext: def __enter__(self): print('enter') return self def __init__(self, a, b): self.a = a self.b = b def __exit__(self, exc_type, exc_val, exc_tb): print('exit') pass def _func1(self): print('do func1', self.a) def _func2(self): print('do func2', self.b) # @contextlib.contextmanager def func(self, c): self._func1() self._func2() print(f'func {c}') return self # 结果: do func1 1 do func2 2 func 3 enter do exit # 方法2:使用装饰器简化 class MyContext: # def __enter__(self): # print('enter') # return self def __init__(self, a, b): self.a = a self.b = b # def __exit__(self, exc_type, exc_val, exc_tb): # print('exit') # pass def _func1(self): print('do func1', self.a) def _func2(self): print('do func2', self.b) @contextlib.contextmanager def func(self, c): self._func1() self._func2() print(f'func {c}') # return self yield self # 结果: do func1 1 do func2 2 func 3 do
- 定义函数
# 自定义装饰器 def wrap_func(func): def wrapper(*args, **kwargs): print('call wrap_func') return func(*args, **kwargs) return wrapper @wrap_func def my_func(x: int, y: int = 2) ->int: z = 5 # 闭包函数 def my_func_sub(): return x + y + z return my_func_sub() print(my_func(10)) # 输出: call wrap_func 17
函数的特殊属性列表:
属性 | 意义 | 读写 |
|
函数的文档字符串,不会被子类继承。 | |
__name__ | 函数名称 | |
__qualname__ | 函数限定名称 | |
__module__ | 函数模块名 | |
__defaults__ | 默认参数值组成的元组 | |
__code__ | 编译后的函数体代码对象 | |
__globals__ | 函数所属模块的全局命名空间 | 只读 |
__dict__ | 命名空间支持的函数属性 | |
__closure__ | 只读 | |
__annotations__ | 参数标注的字典。 | |
__kwdefaults__ | 关键字参数默认值的字典 |
- 定义类
# 简单的类定义 class CalCls: def __init__(self, m=0, n=0): self.m = m self.n = n def add(self): return self.m + self.n def mul(self): return self.m * self.n cls = CalCls(10, 10) print(cls.add()) print(cls.mul()) 输出: 20 100