Python
一、语言
1.编译型语言
编译器把源程序的每一条语句都编译成机器语言,并保存成二进制文件,运行时计算机可以直接以机器语言来运行程序,速度快。
- 优点:编译器一般会有预编译的过程对代码进行优化。只编译一次,运行时不需要编译,编译型语言的程序执行效率高,可脱离语言环境独立运行。
- 缺点:编译之后如果需要修改就需要整个模块重新编译,编译的时候根据对应的运行环境生成机器码,不同的操作系统之间的移植存在问题,需要根据运行的操作系统环境编译不同的可执行文件。
2.解释型语言
解释器在执行程序时,将一条一条的语句解释成机器语言给计算机执行,运行速度不如编译后的程序运行快。
- 优点:良好的跨平台和兼容性,修改代码的时候直接修改就可以,可以快速部署,不用停机维护。
- 缺点:每次运行的时候都要解释一遍,性能上不如编译型语言。
3.静态语言
数据类型是在运行前(如编译阶段)检查的,也就是说在写程序时要声明所有变量的数据类型。
4.动态语言
运行阶段检查数据类型,也就是说在写程序时不用给任何变量指定数据类型,该语言会在你第一次赋值给变量时,在内部将数据类型记录下来。
5.强类型语言
强制数据类型定义的语言。一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型。强类型定义语言是类型安全的语言。
6.弱类型语言
数据类型可以被忽略的语言。它与强类型定义语言相反, 一个变量可以赋不同数据类型的值。弱类型定义语言是类型不安全的语言。
二、基本数据类型
- 不可变数据类型(可哈希):
num、str、tuple(、bool) - 可变数据类型(不可哈希):
list、dict、set tuple子元素不可更改,若子元素为可变数据类型,则可更改子元素dict[key]必须是不可变数据类型set为可变数据类型,但其子元素为不可变数据类型。不可变集合frozenset([iterable])
1.增
list–>append(object)、insert(index, object)、extend(iterable)(add every element from the iterable)dict–>dict[key]= value、setdefault(k[,d])、fromkeys(iterable, value)set–>add(element)、update(iterable)(add every element from the iterable)
2.删
1 | # del关键字 |
list–>pop([index=-1])、remove(object)、clear()、del list、del list[x:y:z]dict–>pop(k[,d])、popitem()、clear()、del dict、del dict[key]set–>pop()(arbitrary)、remove(element)(raise a KeyError if the element is not a member)、discard(element)(do nothing if the element is not a member)、clear()、del set
3.改
list–>list[x:y:z]= valuedict–>update(dict)
4.查
- 索引切片
forstr–>find(sub[, start[, end]])(return the lowest index in substring else return -1)、index(sub[, start[, end]])(return the lowest index in substring else raise ValueError)list–>index(value, [start, [stop]])dict–>keys()、values()、items()、get(k[, d=None])set–> 交集(&、intersection())、并集(|、union())、差集(-、difference())、反交集(^、symmetric_difference())、子集(issubset())、超集(issuperset())
(列表元素去重 —>list=>set)
1 | # 交集(&、intersection()) |
1 | # 并集(|、union()) |
1 | # 差集(-、difference()) |
1 | # 反交集(^、symmetric_difference()) |
1 | # 超集(issuperset())、子集(issubset()) |
5.运算符及优先级
逻辑运算符
| 逻辑运算符 | 逻辑表达式 | 描述 |
|---|---|---|
| not | not x | x -> True = False else True |
| and | x and y | x -> True = y else = x |
| or | x or y | x -> True = x else = y |
1 | bool为True或False的情况 |
1 | # 非 not x |
1 | # 与 x and y |
1 | # 或 x or y |
优先级
| 运算符优先级(高->低) | 描述 |
|---|---|
| ()、[] | ()显示设置、[]下标索引 |
| ~ | 按位取反 |
| *、/、%、// | 乘、除、取余、整除 |
| +、- | 加减 |
| >>、<< | 右移、左移 |
| & | 按位与 |
| ^、| | 按位异或、按位或 |
| <=、<、>、>= | 比较运算符 |
| <>、==、!= | 等于运算符 |
| =、%=、/=、//=、-=、+=、*=、**= | 赋值运算符 |
| is、is not | 身份运算符 |
| in、not in | 成员运算符 |
| and、or、not | 逻辑运算符 |
| if else | 条件表达式 |
| lambda | lambda表达式 |
6.else语句
如果
while循环中存在else代码块,它将总是被执行,除非通过break语句来中断这一循环(此时不会执行else语句块)。
对于for循环,else部分同样是可选的,当循环中包含else时,总会在for循环结束后开始执行,除非遇到了break语句(此时不会执行else语句块)。
try…except…else,else语句在未发生异常时执行。
with语句会获取由open语句返回的对象,并在代码块开始之前调用__enter__,在代码块执行完之后调用__exit__。assert(断言)用来判断其后一句的正确与否,若错误,则抛出AssertionError。
7.深浅拷贝
is用于判断两个变量引用对象是否为同一个,==用于判断引用变量的值是否相等。
1 | # 赋值运算:指向同一个内存地址,完全一样。 |
1 | # 浅拷贝:在内存中重新创建了一个空间存放新列表,新列表中的元素与原列表中的元素是公用的。 |
1 | # 深拷贝:列表是在内存中重新创建,列表中可变的数据类型是重新创建的,列表中的不可变的数据类型是公用的。 |
8.转换
str —> bytes
str.encode()
1 | > str1 = '你好' |
bytes —> str
bytes.decode()
1 | > str1 = b'\xe4\xbd\xa0\xe5\xa5\xbd' |
str —> list
str.split()
1 | > str1 = 'abcdefg' |
list —> str
“”.join(list)
1 | >> list1 = ['abcde', 'fg'] |
dict —> json
json.dumps()
json.dump()
1 | > list_1 = [{"name": "张三", "age": 20}, {"name": "李四", "age": 18}] |
json —> dict
json.loads()
json.load()
1 | > data = '[{"name":"张三","age":20},{"name":"李四","age":18}]' |
json —> csv
1 | >> import json |
9.序列化和反序列化
变量从内存中变成可存储或传输的过程称之为序列化。把变量内容从序列化的对象重新读到内存称之为反序列化。
1 | # pickle |
1 | # json |
1 | # shelve |
10.编码
1 | 一些典型编码 |
- 文件的储存、传输不能是Unicode(只能是ASCII,UTF-8,GBK…..)
- Python2默认编码ASCII,Python3默认编码UTF-8
- Python3中字符串str用Unicode编码
1 | # ASCII |
1 | # Unicode |
1 | # UTF-8 |
1 | # GBK |
1 | # 对于英文 |
1 | # 对于中文 |
三、函数
1.函数传参顺序
def func(位置参数, 可变参数*args, 默认参数, 关键字参数**kwargs): pass
1 | > def parameter(name, age, *args, sex='男', no='12', **kwargs): |
若函数默认参数的值是可变数据类型,则每次调用函数时,默认参数如果不传值就会公用这个数据类型
1 | > def func(k, l={}): #Pycharm提示'Default argument value is mutable' |
2.函数名
函数名就是内存地址,可以赋值,可以作为容器类型的元素,可以作为函数的返回值,可以作为函数的参数
1 | def func(): |
3.内建模块
1 | # Python v3.6.6 |
| builtins(Python3) | description(详见builtins.py) |
|---|---|
| ArithmeticError | 所有数值计算错误的基类 |
| AssertionError | 断言语句失败 |
| AttributeError | 对象没有这个属性 |
| BaseException | 所有异常的基类 |
| BlockingIOError | I/O operation would block |
| BrokenPipeError | Broken pipe |
| BufferError | Buffer error |
| BytesWarning | mostly related to conversion from str or comparing to str |
| ChildProcessError | Child process error |
| ConnectionAbortedError | Connection aborted |
| ConnectionError | Connection error |
| ConnectionRefusedError | Connection refused |
| ConnectionResetError | Connection reset |
| DeprecationWarning | 关于被弃用的特征的警告 |
| EOFError | 没有内建输入,到达EOF标记 |
| Ellipsis | Ellipsis represents ‘…’ in slices |
| EnvironmentError | 操作系统错误的基类 |
| Exception | 常规错误的基类 |
| False | False |
| FileExistsError | File already exists |
| FileNotFoundError | File not found |
| FloatingPointError | 浮点计算错误 |
| FutureWarning | 关于构造将来语义会有改变的警告 |
| GeneratorExit | 生成器(generator)发生异常来通知退出 |
| IOError | 输入/输出操作失败 |
| ImportError | 导入模块/对象失败 |
| ImportWarning | probable mistakes in module imports |
| IndentationError | 缩进错误 |
| IndexError | 序列中没有此索引(index) |
| InterruptedError | Interrupted by signal |
| IsADirectoryError | Operation doesn’t work on directories |
| KeyError | 映射中没有这个键 |
| KeyboardInterrupt | 用户中断执行(通常是输入^C) |
| LookupError | 无效数据查询的基类 |
| MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
| ModuleNotFoundError | Module not found |
| NameError | 未声明/初始化对象 (没有属性) |
| None | None |
| NotADirectoryError | Operation only works on directories |
| NotImplemented | Method or function hasn’t been implemented yet |
| NotImplementedError | 尚未实现的方法 |
| OSError | 操作系统错误 |
| OverflowError | 数值运算超出最大限制 |
| PendingDeprecationWarning | 关于特性将会被废弃的警告 |
| PermissionError | Not enough permissions |
| ProcessLookupError | Process not found |
| RecursionError | Recursion limit exceeded |
| ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
| ResourceWarning | resource usage |
| RuntimeError | 一般的运行时错误 |
| RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
| StopAsyncIteration | Signal the end from iterator.__anext__() |
| StopIteration | 迭代器没有更多的值 |
| SyntaxError | Python 语法错误 |
| SyntaxWarning | 可疑的语法的警告 |
| SystemError | 一般的解释器系统错误 |
| SystemExit | 解释器请求退出 |
| TabError | Tab 和空格混用 |
| TimeoutError | Timeout expired |
| True | True |
| TypeError | 对类型无效的操作 |
| UnboundLocalError | 访问未初始化的本地变量 |
| UnicodeDecodeError | Unicode 解码时的错误 |
| UnicodeEncodeError | Unicode 编码时错误 |
| UnicodeError | Unicode 相关的错误 |
| UnicodeTranslateError | Unicode 转换时错误 |
| UnicodeWarning | Unicode conversion problems |
| UserWarning | 用户代码生成的警告 |
| ValueError | 传入无效的参数 |
| Warning | 警告的基类 |
| WindowsError | 系统调用失败 |
| ZeroDivisionError | 除(或取模)零 (所有数据类型) |
| __build_class__ | \ |
| __debug__ | \ |
| __doc__ | \ |
| __import__ | \ |
| __loader__ | \ |
| __name__ | \ |
| __package__ | \ |
| __spec__ | \ |
| abs | 详细信息 |
| all | 详细信息 |
| any | 详细信息 |
| ascii | 详细信息 |
| bin | 详细信息 |
| bool | 详细信息 |
| bytearray | 详细信息 |
| bytes | 详细信息 |
| callable | 详细信息 |
| chr | 详细信息 |
| classmethod | 详细信息 |
| compile | 详细信息 |
| complex | 详细信息 |
| copyright | 详细信息 |
| credits | 详细信息 |
| delattr | 详细信息 |
| dict | 详细信息 |
| dir | 详细信息 |
| divmod | 详细信息 |
| enumerate | 详细信息 |
| eval | 详细信息 |
| exec | 详细信息 |
| exit | 详细信息 |
| filter | 详细信息 |
| float | 详细信息 |
| format | 详细信息 |
| frozenset | 详细信息 |
| getattr | 详细信息 |
| globals | 详细信息 |
| hasattr | 详细信息 |
| hash | 详细信息 |
| help | 详细信息 |
| hex | 详细信息 |
| id | 详细信息 |
| input | 详细信息 |
| int | 详细信息 |
| isinstance | 详细信息 |
| issubclass | 详细信息 |
| iter | 详细信息 |
| len | 详细信息 |
| license | 详细信息 |
| list | 详细信息 |
| locals | 详细信息 |
| map | 详细信息 |
| max | 详细信息 |
| memoryview | 详细信息 |
| min | 详细信息 |
| next | 详细信息 |
| object | 详细信息 |
| oct | 详细信息 |
| open | 详细信息 |
| ord | 详细信息 |
| pow | 详细信息 |
| 详细信息 | |
| property | 详细信息 |
| quit | 详细信息 |
| range | 详细信息 |
| repr | 详细信息 |
| reversed | 详细信息 |
| round | 详细信息 |
| set | 详细信息 |
| setattr | 详细信息 |
| slice | 详细信息 |
| sorted | 详细信息 |
| staticmethod | 详细信息 |
| str | 详细信息 |
| sum | 详细信息 |
| super | 详细信息 |
| tuple | 详细信息 |
| type | 详细信息 |
| vars | 详细信息 |
| zip | 详细信息 |
1 | """ Return the absolute value of the argument. """ |
1 | """ |
1 | """ |
1 | """ |
1 | """ |
1 | """ |
# bytearray([source[, encoding[, errors]]])
1 | """ |
# bytes([source[, encoding[, errors]]])
1 | """ |
1 | """ |
1 | """ Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff. """ |
1 | """ |
# compile(source, filename, mode[, flags[, dont_inherit]])
1 | """ |
1 | """ |
1 | """ |
1 | """ |
1 | """ |
1 | """ |
1 | """ |
1 | """ Return the tuple (x//y, x%y). Invariant: div*y + mod == x. """ |
# enumerate(sequence, [start=0])
1 | """ |
# eval(expression[, globals[, locals]])
1 | """ |
# exec(object[, globals[, locals]])
1 | """ |
1 | pass |
1 | """ |
1 | """ Convert a string or number to a floating point number, if possible. """ |
1 | """ |
| 输入 | 格式化 | 输出 | 描述 |
|---|---|---|---|
| 1.123456 | {:.2f} | 1.12 | 保留小数点后两位 |
| 1.123456 | {:+.2f} | +1.12 | 带符号保留小数点后两位 |
| -1.123456 | {:-.2f} | -1.12 | 带符号保留小数点后两位 |
| 1.123456 | {:.0f} | 1 | 四舍五入不带小数 |
| 1.523456 | {:.0f} | 2 | 四舍五入不带小数 |
| 1523456 | {:10d} | 1523456 | 宽度为10,默认右对齐 |
| 1523456 | {:>10d} | 1523456 | 宽度为10,右对齐,默认空格填充 |
| 1523456 | {:*10d} | ***1523456 | 宽度为10,右对齐,*填充 |
| 1523456 | {:^10d} | 1523456 | 宽度为10,居中对齐,默认空格填充 |
| 1523456 | {:#^10d} | #1523456## | 宽度为10,居中对齐,#填充 |
| 1523456 | {:<10d} | 1523456 | 宽度为10,左对齐,默认空格填充 |
| 1523456 | {:&<10d} | 1523456&&& | 宽度为10,左对齐,&填充 |
| 1523456 | {:,} | 1,523,456 | 逗号分隔的数字 |
| 1523456 | {:.0%} | 152345600% | 百分制,保留小数点0位 |
| 1523456 | {:.2%} | 152345600.00% | 百分制,保留小数点2位 |
| 1523456 | {:.0e} | 2e+06 | 科学计数法,保留小数点0位 |
| 1523456 | {:.2e} | 1.52e+06 | 科学计数法,保留小数点2位 |
| 10 | {:b} | 1010 | 二进制转换 |
| 10 | {:#b} | 0b1010 | (“带头”)二进制转换 |
| 10 | {:o} | 12 | 八进制转换 |
| 10 | {:#o} | 0o12 | (“带头”)八进制转换 |
| 10 | {:d} | 10 | 十进制转换 |
| 10 | {:x} | a | 十六进制转换 |
| 10 | {:#x} | 0xa | (“带头”)十六进制转换 |
| 10 | {:X} | A | 十六进制转换(大写) |
| 10 | {:#X} | 0xA | (“带头”)十六进制转换(大写) |
| 好 | {!a} | ‘\u597d’ | ascii() |
| 10 | {!s} | 10 | str() |
| 10 | {!r} | 10 | repr() |
1 | """ |
# getattr(object, name[, default])
1 | """ |
1 | """ |
1 | """ |
1 | """ |
1 | """ |
1 | """ |
1 | """ |
1 | """ |
1 | """ |
# isinstance(object, classinfo)
1 | """ |
# issubclass(object, classinfo)
1 | """ |
1 | """ |
1 | """ Return the number of items in a container. """ |
1 | """ |
1 | """ |
1 | """ |
1 | """ |
1 | """ |
1 | """ Create a new memoryview object which references the given object. """ |
1 | """ |
1 | """ |
1 | """ The most base type """ |
1 | """ |
# open(file, mode=’r’, buffering=None, encoding=None, errors=None, newline=None, closefd=True)
1 | pass |
1 | """ Return the Unicode code point for a one-character string. """ |
1 | """ |
# print(*objects, sep=’ ‘, end=’\n’, file=None)
1 | """ |
1 | """ |
1 | pass |
1 | """ |
1 | """ |
1 | """ Return a reverse iterator over the values of the given sequence. """ |
1 | """ |
1 | """ |
# setattr(object, name, value)
1 | """ |
1 | """ |
# sorted(iterable, key=None, reverse=False)
1 | """ |
1 | """ |
1 | """ |
1 | """ |
# super(type[, object-or-type])
1 | """ |
1 | """ |
1 | """ |
1 | """ |
1 | """ |
# reduce(function, sequence, initial=None)
1 | """ |
4.装饰器
不修改函数的调用方式,在原来的函数前后添加功能。开放(扩展是开放的)封闭(修改是封闭的)原则。
1 | 闭包:嵌套函数,内部函数对外部函数(非全局)变量的引用 |
1 | 装饰器装饰不带参数的函数 |
1 | 装饰器装饰带参数的函数 |
1 | 带参数的装饰器 |
1 | 多个装饰器装饰一个函数 |
1 | # 由于调用被装饰函数实际调用装饰器中的内层函数,所以被装饰函数会丢失信息如__name__、__doc__、__module__,为了防止此类现象的发生,调用functools模块中的wraps装饰器,可将原函数对象的指定属性复制给包装函数对象。 |
1 | # 完整通用装饰器模板 |
5.迭代器
可迭代(iterable):含有
__iter__()方法(__getitem__())是可迭代的(可迭代协议)
迭代器(iterator):含有__next__()和__iter__()方法的是迭代器(迭代器协议)
迭代器一定可迭代,可迭代的可被for循环,可被for循环的可迭代iterable.__iter__()= >迭代器iterator.__next__()从迭代器中一个一个取值
迭代器的好处:不会一次性在内存中生成全部数据占用很大内存,而是每次利用__next__()获取一个值时,会生成一个,直到获取完所有的值,节省内存空间;惰性机制;不能反复,只能向下执行
for循环迭代器只会循环一次,需要一个值,生成一个值,直至取完迭代器中所有元素位置
for循环非迭代器(如列表等可迭代的数据类型)每次从头开始
1 | >> print('__iter__' in dir(bool)) |
1 | 通过collections模块的Iterable判断对象是否可迭代 |
6.生成器
generator生成器和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而generator生成器函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行
生成器本质是迭代器
含有yield关键字的函数都是生成器函数。首先利用def定义一个生成器函数,接着调用生成器函数,函数不会执行,而是会创建一个生成器,最后利用创建的生成器进行取值操作。
yield不能和return共用且yield需要写在函数内
生成器的惰性机制: 生成器只有在访问的时候才取值,你找它要才给你值,不找它要,它是不会执行的
生成器取值:next()、for、数据类型强转(占用内存)
1 | 生成器函数 |
1 | send()的效果和next()一样,只是在获取下一个值的时候,send()会给上一个yield的位置传递一个数据 |
1 | >> def func(): |
1 | yield from |
1 | 预激活生成器的装饰器(通俗的说就是让生成器执行到有yield关键字的地方挂起) |
1 | 生成器表达式 用() |
7.偏函数
在使用标准化参数时,如果函数参数偏多,可以设置默认参数,降低函数调用的复杂度。利用
Python的functools模块提供的partial函数(偏函数),将带有n个参数的函数,固化一个参数(如果不指定关键字,则固化第一个参数),并返回另一个带有n-1个参数的函数对象。
1 | > from functools import partial |
四、面向对象
1.概念
通常情况下,在类中定义的所有函数都是对象的绑定方法,对象在调用绑定方法时会自动将自己作为参数传递给方法的第一个参数(默认是self)
1 | > class Test: |
当定义了一个class并创建了该类的实例后,可以给该实例动态绑定属性和方法。
1 | > class Student: |
使用
__slots__限制绑定的属性
使用__slots__定义的属性仅对当前类实例起作用,对继承的子类不起作用,除非在子类中也定义__slots__,则子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。
1 | > class Student: |
组合:一个对象的属性是另外一个类的对象
1 | > class A: |
三大特性:继承、多态、封装
继承
当在父类和子类中都定义了
__init__方法时,Python不会自动调用父类的__init__方法,必须显式地在子类中调用它。相反,当没有在子类中定义__init__方法时,会默认调用父类的__init__方法。(方法的重写)
1 | 继承 |
1 | # Python3新式类多继承(广度优先) |
1 | # Python2经典类多继承(深度优先) |
1 | # 接口类 |
1 | # 抽象类 |
三大特性:继承、多态、封装
多态
1 | Python默认支持多态。多态的前提是继承。 |
三大特性:继承、多态、封装
封装
1 | 私有静态属性__name、私有属性__self.age、私有方法__func(self) |
1 | # @property把类中的方法变为属性直接调用(执行以后返回) |
1 | # @staticmathod 类中没有默认参数的方法 |
1 | # @classmethod 类中的方法只涉及静态属性,可以直接被类调用,不必通过对象调用 |
2.反射
应用:根据字符串的形式导入模块、根据字符串的形式去对象(某个模块)中操作其成员
1 | hasattr、getattr、setattr、delattr |
3.元类
type(arg1, arg2, arg3)函数既可以返回一个对象的类型,又可以创建出新的类。
arg1为class的名称,arg2为继承的父类集合,arg3为class的方法名与函数绑定。
通过type()函数创建的类和直接写class是完全一样的,因为Python解释器遇到class定义时,仅仅是扫描class定义的语法,然后调用type()函数创建出class。
1 | type注释 |
1 | > def fn(self, name='world'): |
除了使用type()动态创建类以外,要控制类的创建行为,还可以使用metaclass。metaclass允许创建类或修改类。可以把类看作是metaclass创建出来的实例。即先定义metaclass,就可以创建类,最后创建实例。(Django ORM)
4.类的内置方法
1 | __new__ 构造方法 |
1 | __str__和__repr__、str()和repr() |
1 | __del__、del |
1 | __iter__、iter() |
1 | __getitem__、__setitem__、__delitem__ |
1 | # __getattribute__、__getattr__、__setattr__、__delattr__ |
1 | # __call__ |
5.元类
1 | 创建类时先执行type的__init__方法,类实例化时执行type的__call__方法,__call__方法的返回值就是实例化的对象。(在__call__方法中先执行类的__new__方法生成实例化对象,然后执行__init__方法初始化对象,最后返回对象) |
五、模块和包
在程序开发中,一个 Python 模块可能在多处被 import,但是 Python 只会加载其一次,这是因为 Python 将所有加载到内存的模块都放在 sys.modules 中,在加载新的模块时会先在sys.modules 列表中查找是否已经加载该模块,如果加载了,则只将模块的名字加入到调用模块的 Local 名称空间中;如果没有加载,则搜索模块、载入内存,并更新 sys.modules。加载模块会导致这个模块被“执行”。也就是说被导入模块的顶层代码将直接被执行。这通常包括设定全局变量以及类和函数的声明。加载模块时不想被运行的代码应尽可能地封装到函数中,只把函数和模块定义放入模块的顶层是良好的模块编程习惯。
未完待续…