###########学习手册
###########基础教程
###########chapter_01
# 简介
# python是一门多用途语言，市场扮演脚本语言的角色，定义未面向对象语言
# python的执行速速不够快

###########chapter_02
# 解释器是一种让其他程序运行起来的程序，python解释器读取程序，按照其中命令执行；运行python程序的程序
# 解释器是代码和计算机硬件之间的软件逻辑层
# 程序如何执行的：对源码编译成字节码形式，再发送到python虚拟机上执行，再解释
# psyco实时编译器，可以让程序运行得更快，是一个pvm增强工具，专有的JIT即时编译器，只能适应INTEL X86芯片
# shedskin c++转换器，将python代码转化为c++
# py2exe,pyinstaller可以冻结二进制文件（不需要环境来运行python程序）

###########chapter_03
# import os
# print(os.getcwd())
# 流重定向：python xxx.py > xxx.txt
# 输入流的重定向：python xxx.py < input.txt
# import xxx只会导入一次； import imp :imp.reload(xxx)可以再次导入
# exec与import有相同的效果，但是不会导入模块，而且会导致变量被覆盖的情况

###########chapter_04_数据类型
# python核心数据类型：数字、字符串、列表、字典、元组、文件、集合、None、布尔型、函数、模块、类、编译的代码堆栈跟踪
# import math
# print(math.pi)
# import random
# print(random.random())
# print(random.choice([1,2,3,4]))
# 不可变性：数字、字符串、元祖
# 格式化操作
# 1: '%s ,eggs,and,%s ' %s ('xxx','yyy')
# 2: '{0} ,eggs,and,{1} '.format('xxx','yyy')
# dir(x) 获得对象操作方法
# help(x) 返回该函数用法
# python的核心数据类型支持任意的嵌套
# 列表解析表达式：[x for x in range(10) ]
# 生成器：A=(x for x in range(10))  next(A)
# 集合与字典的区别：集合没有键值对应，字典有键值对应
# 为了简单和可读性编写代码
# 多态意味着一个操作符（如+）的意义取决于被操作的对象，这将变成使用好python的关键思想之一，不要把代码限制在特定的类型上，是代码自动适用于多种类型

###########chapter_05_数字
# 三元选择表达式 x if y else z
# x=3
# print('22') if x>2 else print('2')
# 整数转换，浮点数转换：int(),float()
# repr是默认的交互模式回显,str是打印语句，更加友好
# 真除法X/Y 地板除法X//Y 只保留整数
# math.pow(2,3)求幂
# random.randint(x,y)求X,Y间的随机数
# random.choice([x,y,z])
# 小数数字??decimal
# 分数??fractions
# 集合：唯一、无序、无重复元素,set(x),列表去重list(set(x)),可以看做是无值的字典，字典和列表不能嵌入到集合中，
# 布尔值True False

###########chapter_06_动态类型
# 变量必须在使用前赋'值' x=3 变量名为x的引用对象3，变量事实上是到对象内存空间的一个指针
# 创建一个对象来代表值3   创建一个变量a   将变量与新的对象3相连接
# 类型属于对象，而不是属于变量，对象包含了一个头部信息，标记了这个对象的类型以及值
# 垃圾收集器主要基于引用计数器，当引用计数器为零时，就会被回收，从而释放空间；同时计数器不为零时，不会被回收，占内存
# python拷贝对象,而不是创建引用，这样不会造成2个变量对同一列表共享引用时，其中一个变量修改对象，导致另外一个变量值同时变化的问题
# 拷贝对象：copy,copy.copy()
# ==是检查是否有相同的值，is是检查对象的同一性(是否为同一对象)
# x=[1,2,3],y=x 这代表是精确的指向同一对象 y is x
# x=[1,2,3],y=[1,2,3],y is not x
# sys.getrefcount(x) 查询对象引用次数

###########chapter_07_字符串
# ''==""：单引号等于双引号
# 转义序列：反斜杠\
# raw:r'xxxx'关闭转义机制
# x[:]实现顶层x拷贝
# 格式化字符串方法：替换标识中加冒号，跟指定字段大小、对齐方式、特定类型编码的格式化声明
# '{}'.format(1)
# '{0}{1}'.format(1,2)
# '{hello}'.format(hello='2')
# 'xxx{:<9}xxx'.format(2)
# 'xx{0:10.{1}f}xxxx'.format(1,2)#{:}左边代表索引，右边是具体方法
# 格式化字符串表达式：'%s' % (1)
# 修改字符串之后要重新赋值
# x.replace(x,y,index)
# list(x)与''.join(x)互补
# x.split()
# x.strip()删除2边空白符x.rstrip()删除右边空白符
# 字符串格式化单独format函数：format(x,'.2f')
# 连续替换多个字符'zzzzzzz'.tanslate(str.maketrans('xx','yy'))

###########chapter_08_列表与字典
# 列表（有序的集合）
# map函数
# def f(x):
# 	return x*x
# for i in map(f,[1,2,3,4,5]):
# 	print(i)
# a=map(f,[1,2,3,4,5])
# print(list(a))
# 插入操作，是先删除后插入
# 内置函数sorted和sort方法
# 字典（无序的集合）
# 合并x.update()
# 取值x.get()
# 字典解析{x:x for x in LIST}

###########chapter_09_元祖、文件及其他
# 元祖不能修改，只适用于元祖顶层并非其内容
# input('enter:')
# 文件读写r(读)默认值代表输入打开文件，w(写)代表输出生成并打开文件，a代表在文件尾部追加打开，+代表输入和输出打开文件(读写操作)
# pickle模块，超级通用的数据格式化和解析工具
# 拷贝方法：分片表达式x[:]、字典copy方法x.copy()、copy标准库、内置函数list(x)
# 分片和字典copy只能做顶层复制，不能够完全复制嵌套的数据结构；需要深层嵌套的数据结构需要copy模块的deepcopy()
# 即使是类型本身在python中也是对象类型
# read()返回整个文件内容字符串,readline()返回下一行内容字符串,readlines()返回整个文件列表

###########chapter_10_语句简介
# 1.程序由模块构成
# 2.模块包含语句
# 3.语句包含表达式
# 4.表达式建立并处理对象
# python支持用分号;来代表语句结束：x=1;y=2;print(x+y)
# 符合语句的主体可以出现在python的首行冒号之后if 2>1 : print('ture')或者三元语句print('ture') if 1>1 else print('false')
# 捕获异常try except
# 使用assert充当检查点:assert a>0 ,'a must bigger than zero'\n print('a>0')

###########chapter_11_赋值_表达式_打印
# 赋值语句：显示赋值和隐式赋值(导入模块)
# 多目标赋值语句
# 增强赋值语句通常执行更快 x+=1
# 变量名命名规则：必须以下划线或者字母开头，后面接任意数目的字母、数字、下划线
# 变量名区分大小写
# python3.x重定向流：print('hello',file=open('test.csv','w'))

###########chapter_12_if测试和语法规则
# if语句
# if : elif :else
# 缩进是python语法中的一部分
# 三元表达式
# if x:
# 	A=Y
# else:
# 	A=Z
# 转换：A = Y if x else Z
# 短路计算：X = 0 or [] or 1

###########chapter_13_while和for循环
# while循环
# print('ss',end=' ') end代表使所有输出都出现在同一行，用空格隔开
# break 跳出循环；continue 暂停此次循环下次继续；pass 站位符不做任何操作；else 当循环正常离开时才会执行
# while:
# 	x
# else:
# 	y
# for循环
# for循环比while循环快
# zip会取得一个或多个序列为参数，返回元祖的列表；长度不同时，zip会以最短序列的长度为准来截断所得到的元祖
# zip创建字典：dict(zip(a,b))
# 产生偏移和元素enumerate函数

###########chapter_14_迭代器和解析_第一部分
# 迭代器
# _next_或者next()优于readline,内存不会爆炸
# 列表解析运行更快（比for循环快一倍），编写精简
# 扩展列表解析语法：添加if
# 允许任意数目的for子句：[x+y+z for x in range(x) for y in range(y) for z in range(z)]
# range和map、zip、filter不同，前者支持相同结果上的多个活跃迭代器，即前者的多个迭代器会记录自己的位置，而不是共同的位置

###########chapter_15_文档
# #号是标注
# dir()获取对象内可用所有属性列表的简单方式
# help()获取对象帮助文档

###########chapter_16_page(432)_函数基础
# 函数为了最大程度的重用和最小化代码冗余提供的基本的程序结构
# 在python中每个操作都是多态的操作（多态意味着支持多种类型）
# 本地变量

###########chapter_17_page(448)_作用域
# 在代码中给一个变量赋值的地方决定了这个变量将存在于那个命名空间
# def内（本地变量）、嵌套的def内（非本地变量）、def之外（全局变量）
# 本地作用域、上一层结果中def或lanmbda的本地作用域(嵌套作用域)、之后是全局作用域、最后是内置作用域
# 内置作用域和全局作用域在任何地方都可以直接引用/使用,不用传参
# global是一个命名空间的声明,全局变量
# nonlocal是嵌套函数中，顶层函数的声明，即如果b函数中有a函数，在a函数中声明了nonlocal x，那么此时b函数内(包含a函数)中x的值就变为a函数中x的值,即nonlocal修改了上一层函数定义x的值
# 尽量避免使用全局变量，通过传递函数然后返回至来替代一下
# 闭合或者工厂函数：一个能够记住嵌套作用域的变量值的函数,即嵌套函数
# 避免在def中嵌套def

###########chapter_18_page(477)_参数
# 注意可变对象和不可变对象传入函数时，是否会影响值的改变
# 调用顺序：value,name=value,*sequence(元祖),**dict(字典)
# 参数顺序：name,name=value,**name
# 函数可以作为参数传入函数
# keyword-only参数必须在一个单个星号后面指定
# 参数通过赋值传递到函数中，赋值方式是通过对象引用
# 关键字参数：在调用时指定参数名称，也可以指定默认值
# *args:得到一个元组
# **args:得到一个字典

###########chapter_19_page(505)_函数的高级话题
# 递归函数：直接或间接的调用自身以进行循环的函数
# 迭代是函数内某段代码实现循环：重复反馈过程的活动
# 函数的内省：允许探索实现细节
# 可以使用函数属性，而不必使用全局、非本地和类等其他技术
# 函数注解
# 匿名函数lambda：没有函数名，创建了一个调用的函数，但是返回了一个函数;优点：简洁的代码结构；只允许单个的返回至表达式
# f=lambda x : x**2 
# 如果在lambda函数中进行print,建议直接写sys.stdout.write(str(x)),因为print实际就是sys.stdout.write
# 避免使用嵌套的lambda
# 映射函数：map(function,iterable,iterable,...)结果返回一个新的列表，比for循环更快
# 函数式变成工具：filter,reduce
# 过滤函数：filter(function,iterable)
# reduce返回单个结果,与map相似,2元函数
# 编写函数通常应该较小，尽可能包含单一、统一的用途；并且与输入参数和返回值等其他部分通信

###########chapter_20_page(527)_迭代和解析_第二部分
# 列表解析要比map,filter简单方便得多：map调用要比for循环快2倍,列表解析要比map调用快一些
# map和列表解析的最大区别是：map是一个迭代器，根据需求产生结果；列表解析必须编码为生成器表达式，节省内存
# 测试程序的速度，需要调用time.perf_counter()和time.time()
# 生成器：生成器函数def yield;生成器表达式(i for i in range(10))
# 生成器不是一次计算出所有的值，而是每次计算一个，这样节约内存使用
# 怎么计算对象占用内存大小？？？
# 生成器中send和next方法，还支持throw(type)
# 生成器是单次迭代对象
# iter是迭代器
# 集合解析：set(i for i in range(10))或者{x for x in range(10)}
# 字典解析：dict((x,x**2) for x in range(10))或者{x:x**2 for x in range(10)}
# 代码性能检验，模块计时器
# 函数陷阱
# 没有return语句的函数返回none
# timeit.timeit(stmt='func',repeat=times,number=times)

###########chapter_21_page(572)_模块
# 模块是最高级别的程序组织单元，它将程序代码和数据封装起来以便重用
# 导入会执行三个步骤：1.找到模块文件；2.编译成位码(需要时)；3.执行模块的代码来创建其所定义的对象
# sys.modules.keys()可以查看当前已导入的模块
# import搜索的目录：1.程序的主目录 2.pythonpath目录 3.标准连接库目录 4.任何.pth文件的内容(lib/site-packages/目录下创建.pth文件(多个路径以回车分隔))

###########chapter_22_page(586)_模块代码编写基础
# 文件顶层的赋值会成为模块的属性
# import
# from x import x
# from x import *
# 推荐使用import 而不是 from ... import ...;后者容易破坏命名空间
# 模块其实是变量名的封装
# 命名空间能通过属性__dict__和dir()获取
# 模块绝对无法看见其他函数内的变量名，除非物理上处理这个函数
# 模块程序代码绝对无法看见其他模块内的变量名，除非明确进行了导入
# reload()函数会强制已加载的模块代码重新载入并重新执行
# 模块重载在重启较大系统时的代价很大，所以作用明显

###########chapter_23_page(603)_模块包
# 导入包 improt x.y.z 
# 点号路径时对应与机器上目录的层次和路径
# 包导入语句的路径中的每个目录内都必须有__init__.py(可以为空)这个文件，否则导入包会失败
# 包导入和相对导入：1.通过sys.path路径列表上的每个目录来查找从左到右进行 2.包带有一个特殊的__init__.py文件 3.在一个包文件中，常规import语句使用和其他地方的导入一样的sys.path搜索规则

###########chapter_24_page(625)_高级模块话题
# 在模块总隐藏数据
# from * 语句会导出__all__的变量，不会导出_x变量(变量名前加下划线)
# __name__ == '__main__' 最小的单元测试
# 修改模块搜索路径
# python内省机制
# exec函数及eval函数：编译一个代码字符串，并将其传递给python解释器以执行
# 模块设计理念：总是在python的模块内编写代码；模块耦合要降到最低：全局变量；最大化模块的黏合性：统一目标；模块应该少去修改其他模块的变量

###########chapter_25_page(652)_类和oop:宏伟蓝图
# 类是python面向对象程序设计(oop)的主要工具
# 类是一些函数的包
# 特性：继承和组合
# 独到之处：多重实例(一个类可以产生多个实例)，通过继承进行定制，运算符重载
# 由下至上，由左至右搜索attribute首次出现的对象，搜索树
# 类和模块的差异：内存中特定模块只有1个实例(所以需要重载模块取得新代码)，对于类而言，只要有需要，制作多少实例都可以
# __init__是构造函数，初始化
# 类oop是为了代码重用
# self是啥???????????为啥要传self????????????
# 可以理解为self是引用前的定义(比如实例I1.w,那么类的构建函数必须有一个self，否则就不能实例化),书面定义为提供了被处理的实例的参照值
# 私有属性方法或属性(从外部不能访问)：名称以两个下划线打头即可

###########chapter_26_page(664)_类代码编写基础
# 类几乎就是命名空间
# 类主要特性的要点：class语句创建类对象并将其赋值给变量名，class语句内的赋值语句会创建类的属性，类属性提供对象的状态和行为
# 通过在类方法函数外对变量名进行赋值运算，我们甚至可以在实例命名空间内产生全新的属性
# 类通过继承进行定制
# 继承机制的核心观点：超类列在了类开头的括号中，类从其超类中继承属性，实例会继承所有可读取类的属性，每个obj.attribute都会开启新的独立搜索，逻辑的修改是通过创建子类-而不是修改超类
# 在树中较低处发生得重新定义得、取代属性得动作称为重载
# 类名需要大写，函数名小写
# 重载运算符主要概念：1.以双下划线命名得方法(__x__)是特殊得钩子 2.当实例出现在内置运算时,这类方法会自动调用 3.类可以覆盖多数内置类型运算 4.运算符覆盖方法没有默认值,也不需要 5.运算符可让类与python的对象模型相集成
# 只有在实现本质为数学的对象时，才会用到许多运算符重载方法
# x.__dict__查看实例or类属性
# x.__class__查看继承的类
# classname.__bases__查看继承的超类
# 类和模块的关系：类总是位于模块中，类是模块对象的属性；两者都是命名空间，而类支持多个实例、继承、及运算符重载
# 当简单命名的方法够用时，不应该使用运算符重载
# self也是方法调用的隐含的主体(如果缺少,可能无法实例化)
# python_OOP程序代码中最重要的两个概念是:self&__init__
# @property:可以通过.号直接访问方法，使其变成属性；可以检查入参的类型大小等等

###########chapter_27_page(682)_更多实例
# python的类系统实际上很大程度上就是在一堆对象中查找属性，并为函数给定一个特殊的第一个参数
# 用python编程是一种增量原型
# 创建类步骤：
# 步骤一：1.class 类名（类名第一个字母大写）2.编写构造函数 3.在进行中测试
# 步骤二：1.添加行为方法(编写方法)(封装)
# 步骤三：1.运算符重载(__str__,只返回字符串)
# 步骤四：1.通过子类定制行为 2.编写子类 3.编写定制类的方法时，最好使用超类的方法加上参数，这样减少代码维护(instance.method(args...),class.method(self,args...)) 4.多态的作用 5.继承、定制和扩展 5.oop大思路
# 步骤五：1.定制构造函数(在实例对象构造时调用) 2.组合类的其他方式---把对象彼此嵌套以组成复合对象
# 步骤六：1.使用内省工具(dir) 2.特殊类属性(如果一个实例的类定义了__slots__,则实例可能没有存储在__dict__字典中) 3.一种通用的显示工具 4.实例与类属性的关系 5.工具类的命名考虑(避免命名冲突,如果类方法不做其他用途，建议命名前加上单下划线，或者命名前加上双下划线) 6.类的最终形式-通用工具(从模块导入，使用继承将其混合到顶层类中)
# 步骤七：1.把对象存储到数据库中(pickle:任意python对象和字节串之间的序列化，dbm实现一个可通过键访问的文件系统、以存储字符串，shelve使用另两个模块按照键把python对象存储到一个文件中)
# GUI工具：TKinter,Wxpython,PyQt
# 继承是最佳的代码扩展，继承向上传递调用以实现复用，'组合'向下传递以实现'委托'?????????????什么是嵌入函数???????什么是委托?????????

###########chapter_28_page(719)_类代码编写细节
# 1.class语句 2.方法 3.继承 4.类接口技术 5.命名空间 6.文档字符串
# python的class不是声明式的，而是对象的创建者并且是一个隐含的赋值运算：执行时，会产生类对象
# 类几乎就是命名空间，在class语句内赋值的变量名，会创建类属性，而内嵌的def会创建类方法
# 简单的非函数对象赋值给类属性，即为数据属性，由所有实例共享
# 继承搜索只会在属性引用时发生，而不是在赋值运算时发生
# 方法即实例的行为
# 方法一般通过实例调用：如果类和超类都有构造函数，那么没有明确的申明，只会调用子类的构造函数
# 子类可以完全取代继承的属性，提供超类的可以找到的属性，并且通过已覆盖的方法回调超类来扩展超类的方法
# 在子类中调用超类的方法：Superclass.method(self,arg....)
# 常用技巧：1.定义子类中的期待方法 2.无内容，完全继承超类 3.用自己的版本覆盖超类的方法 4.覆盖并回调默认超类中的方法，从而实现定制 5.实现超类中预期的方法
# 抽象超类：'填空'的代码结构一般就是oop的软件框架(在超类中写一个方法名，具体定义及内容在继承的子类中完成)，超类的部分行为默认是由子类提供的
# 命名空间：1.全局作用域/模块 2.本地作用域 3.类属性 4.类方法中的本地变量 5.实例属性
# 模块与类的区别：模块(1.是数据/逻辑包 2.通过导入使用 3.通过编写PYTHON文件来创建) 类(1.实现新的对象 2.由class语句创建 3.通过调用来使用 4.总是位于模块中)

###########chapter_29_page(743)_运算符重载
# 运算符重载：在类方法中拦截内置的操作
# __init__：是构造函数，初始化
# __call__：当为函数API编写接口时，会非常有用，这可以编写遵循所需要的函数来调用接口对象，同时又能保存状态信息
# __del__：析构函数，当实例空间被收回时，自动执行

###########chapter_30_page(774)_类的设计
# oop概念：继承，多态，封装
# oop和继承：是一个关系
# oop和组合：有一个关系，组合涉及把其他对象潜入容器对象内，并使其实现容器方法？？
# oop和委托：包装对象
# 类的伪私有属性：self.__x(属性名前加2个下划线，表示伪私有属性)
# 方法是对象：绑定或无绑定,无绑定类方法对象(无self),绑定实例方法对象(self+函数对)
# 可以将绑定方法赋值给一个变量名，再进行简单调用(推荐此方法)
# 也可以对类进行点号运算，得到无绑定方法对象，但是必须传入实例作为最左侧参数
# 在类中定义一个函数，如果不希望通过实例调用，则在定义时，不需要传入self,直接通过classname.method()调用
# 类是对象：通用对象的工厂，产生任意种类对象的函数，这类函数在OOP设计领域中偶尔称为工厂

###########chapter_31_page(808)_类的高级主题
# 扩展内置类型：通过嵌入扩展类型，通过子类扩展类型
# 新式类：在python3.x中都是新式类，类就是类型
# 新式类的变化：类和类型合并、继承搜索顺序、针对内置函数的属性获取、新的高级工具
# 钻石继承变动：对于经典类class a（深度优先，然后才是由左至右），对于新式类class a(object)（先由左至右，再深度）
# 对类搜索顺序变化，可明确解决冲突：明确指出继承那个类属性（attr=C.attr）
# 新式类的扩展：1.__slots__列表定义该类中只能存在的属性（节省空间和执行速度，而不是为每个实例分配一个字典；使用slot得时候，实例没有__dict__属性字典）
# 类特性
# 静态方法：python3.0直接通过类名.方法进行静态方法调用，或者通过静态方法声明，让实例进行调用func=staticmethod(func)
# 静态方法有利于减少不必要的内存占用和性能消耗
# 类方法：class ... :def func(cls): ...func=classmethod(func)
# 静态方法和显示类名称可能对于处理一个类本地的数据来说是更好的方案
# 类方法可能更适合处理层级中的每个类不同的数据
# 类方法一般和类属性配合使用
# 装饰器??：替函数明确了特定的运算模式，也就是将函数包裹了一层，在另一函数的逻辑内实现(在函数定义上一行@staticmethod@classmethod)
# 类装饰器??元类??：

###########chapter_32_page(856)_异常和工具
# try/except:捕捉由python或你引起的异常并恢复(try不仅会捕捉异常，也会从执行中恢复)
# try/finally:无论异常是否发生，整形清理行为
# raise:手动在代码中出发异常
# assert:有条件的在程序代码中出发异常
# with/as:实现环境管理器
# 类型：错误处理、事件通知、特殊情况处理、终止行为、非常规控制流程
# 捕获异常：try/except
# 引发异常：raise
# 用户定义的异常：类的名称叫做Exception
# 终止行为：try/finally(无论是否发生异常，都执行finally中的语句)

###########chapter_33_page(868)_异常编码细节
# try/except/else：try试着执行的程序代码，except子句定义try代码块内引发的异常的处理器，而else子句则是提供没发生异常时要执行的处理器
# try/finally:略
# try/except/else/finally:略
# raise：显示的触发异常
# assert(条件式引发)：用户的约束条件，而不是捕捉内在的程序设计错误
# with/as环境管理器(作为常见try/finally用法模式的替代方案)：如果是文件打开，则会保证此文件对象会自动关闭(1.解决异常退出时资源释放问题 2.解决用户忘记调用CLOSE方法而产生的资源泄露问题)

###########chapter_34_page(890)_异常对象
# 类的异常特点：1.提供类型分类，对今后的修改有好处 2.附加状态信息 3.他们支持继承
# 字符串异常：略
# 类异常：略
# 内置Exception类：

###########chapter_35_page(905)_异常的设计
# 嵌套try语句(a中嵌套b):如果发生异常，则在b中结束，而不是a
# PyChecker、Pylint:第三方包，检查python程序潜在的问题
# pyunit(unittest):自我测试代码
# doctest:更简单的对代码进行回归测试
# 打包工具：pyinstaller、freeze

###########chapter_36_page(926)_Unicode和字节字符串
# UNICODE通常叫做"宽字符"字符串
# 字节和字符串来回转换：编码，解码
# 略

###########chapter_37_page(971)_管理属性
# 没看懂

###########chapter_38_page(1012)_装饰器
# 装饰：是为函数和类指定管理代码的一种方式
# 函数装饰器：在def末尾，用来增强一个特定函数或方法调用
# 类装饰器：在class的末尾，用来当作一个完整的对象接口
# 装饰器提供了一种方法，在函数和类定义语句的末尾插入自动运行代码（增强对函数和类的调用）
# 函数装饰器语法：看不懂
# 类装饰器：依然没看懂
# 闭包：闭包的本质是嵌套函数，闭包的作用是保存函数的状态信息，是函数的局部变量信息依然可以保存下来，装饰器的本质也是闭包
# 函数装饰器：可以让其他函数在不需要做任何代码变动的前提下增加额外功能
# 类装饰器：类装饰器是管理类的一种方式，不同于单个函数或方法，或者用管理或跨站类所创建的实例的额外逻辑，来包装实例构建调用
# 装饰器嵌套
# 装饰器参数：装饰器封装进一个函数，这个函数的参数就是装饰器参数
# 类装饰器????

###########chapter_39_page(1079)_元类
# 元类是最高级的主题
# 元类最终只是定义自动运行代码的另外一种方式
# 声明元类：class x(metaclass=Meta):...
# 编写元类

###########重复学习重点章节
# 重要章节：第15章、第17章、第19章、第21章、第23章、第24章、第30章、第33章

###########堆(可直接对列表进行操作，不需要转换类型)
# from heapq import *
# heappush(listobj,x):将X压入堆中
# heappop(listobj):从堆中弹出最小元素并删除
# heapify(listobj):让列表具备堆特征
# heapreplace(listobj,x):弹出最小元素，并将X压入堆中
# nlargest(n,iter):返回iter中n个最大的元素
# nsmallest(n,iter):返回iter中n个最小的元素

###########双端队列
# from collections import deque

###########测试
# unittest库
# doctest库

###########性能测试
# timeit.timeit(stmt='func',setup='from __main__ import func_name',number=循环次数)
# cProfile.run('func')

###########深入学习
# hunt、thomas《程序员修炼之道》
# martin《重构》
# gamma、richard《设计模式》
# kent beck《测试驱动开发》
# thomas《算法导论》
# 高德纳《计算机程序设计艺术》