< 个人复习使用 >
python的基础(python万物皆对象)
1.注释
单行注释以#开头
多行注释使用三个单引号将内容括起来,’ ’ ’ xxx ’ ’ ’
程序中使用中文,应该加上中文注释 #coding=utf-8,或者推荐使用 # -- coding=utf-8 --
2.变量(可以使用type来查看变量类型)
-
Number
int、long、float、complex -
布尔
True、False -
String
双引号或者单引号中的数据,就是字符串
切片语法[起点:结束:步长] 字符串、元组、列表都支持切片 -
List
列表中的元素可以是不同的类型
len(x)可以计算字符串、列表、元组的长度
添加元素 l.append(x) 或 l.insert(index, value)
修改元素,通过下标来修改元素
删除元素,下标删除 del l[x] ;删除最后一个l.pop() ; 根据值删除 remove l.remove(x)
in/not in ,value in list 存在返回true -
Tuple
元组的元素不能修改,元组使用小括号( ),列表使用方括号[ ] -
Dictionary
字典的每个元素都分为两部分,key : value,字典使用大括号{ }
添加元素,使用下标d[key]=value,key不存在时,会新增
修改元素 ,下标修改
获取元素 ,使用下标d[key] ,get函数d.get(key)
删除元素 ,del函数del d[key] ,clear函数 d.clear() -
set
集合 -
逻辑运算符
and、or、not -
变量作用域
在函数中修改全局变量,需要使用global进行声明,本质是不能修改全局变量的内存指向,对于可变类型(list…),可以无须使用global声明
在python中值是靠引用来传递的,我们可以用id()来判断两个变量是否为同一个值的引用(id可以认为是地址的标识)。a=1,a=2,此时,a的id发生了改变。 -
可变类型和不可变类型
可变类型:list、dict、set
不可变类型:int、long、bool、float、string、tuple
3.语法句式
-
输出语句
T1 : print(‘xxx%fromat’%value) -
输入语句
T1 : value = raw_input(‘xxx’) 输入的任何值都会作为字符串处理
T2 : value = input() 输入的值必须是表达式,字符串表达式须加双(单)引号"abc"
python3中只有input,且功能等同上面和 -
条件语句
if cond: dothing elif cond: dothing else : dothing
-
循环语句
while cond: dothing #for循环用遍历任何序列的项目 for temp in seq : dothing
4.函数
-
定义
#不支持函数重载 def func(): dothing
-
函数文档说明
在定义函数体第一行用引号引起的内容,外部是用help(func),能够看到相关说明 -
函数参数
函数参数分为位置参数和关键字参数,注意:传参时,关键字参数必须放在位置参数之后
动态参数:按位置传值,多余的参数都有*args接受,保存成一个元组的形式;按关键字传值,多余的参数由**kwargs接受,保存成一个字典的形式
可变参数类型:list、dict -
返回值
如果不写return或只写return,则默认返回None
函数有多个返回值时,要么使用与返回值个数相同的变量去承接,要么使用一个变量去承接
5.文件
文件函数open、read、readline、write、seek、tell、close
6.面向对象编程
-
类
定义方式:
class claname:
func_list -
类的属性
定义对象后,可以通过obj.attr1=xxx,的方法来添加属性(只对该对象有效)
在构造函数中通过self.xx=xxx来添加属性,属性前加 __(双下划线) 为私有属性
类的静态属性,在类定义中直接声明,同样也分为私有和非私有
如果通过对象去修改类属性,类对象会生成一个实例属性去屏蔽类属性,即对象会产生一个同名的实例属性,并不会影响到类属性
类方法:通过@classmethod来修饰,对比与c++类的静态函数,参数为cls;类和实例对象都可以调用;
类实例方法:类实例化对象的方法,参数为self,只有类实例对象可以调用;
静态方法:通过@staticmethod来修饰,不需要定义参数,和该类没有特别的关系,可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护;
类私有属性的原理:属性名前加双下划线的,类会对它的名字作特殊处理,即通过原来的名字不可访问 -
类型的方法
__ init__(self),类的构造函数
__ del__(),类的析构函数
__ new__(cls),类中产生self的函数,在init函数之前执行,必须有返回值(需要用到这个函数时,去网上再查阅下资料)
方法前加 _ _ 为私有方法
形似__func__这样的方法,属于类的魔术方法,需要用到时,应当到网上查阅相关资料 -
继承
语法定义:
class son(father):
funlist
父类的私有属性不能被子类访问
子类构造函数中须调用父类的构造函数super().init(xx) -
多态
和一些面向对象的语言不通,python由于是动态解释语言,其变量需要在运行时才能确定其类型,因此不需要共有的基类来实现多态,而是python特有的“鸭子模型”,类只要实现了需要的方法即可;
7.异常
- 异常关键字:try、except(x1,x2)捕获异常、finally、raise
- 如果没有抛出异常关键字,程序遇到异常时,默认会从异常处返回到上一个函数中寻找捕捉
8.模块
-
import 关键字
当解释器遇到import module 时,会在当前的搜索路径中搜索需要导入的模块
可以使用 from module import func,value 的方式导入模块中的函数和全局变量等
使用as可以给导出模块取别名 -
定位模块
搜寻模块的顺序:当前目录 - 环境变量PYTHONPATH - 默认路径,Unix下默认路径为/usr/local/lib/python。
模块的搜索路径可以在,system模块的sys.path变量中查看。 -
定义自己的模块
每个py文件都可以当做一个模块,文件名就是模块名。
__ name__,python在执行一个文件时使用的变量,当直接执行文件时 (python3 xx.py) ,该变量值为" __ main__ ";导入引用该文件时,变量值为文件名;
__ all__,当此变量在模块中被定义时,该模块中只有这个变量的值才能被其他模块导入;无论是在包的__init__.py中,还是在模块中,__all__变量主要用于from xx import *时导入特定的内容 (*表示导入模块中的所有,而all的变量可以保证只有该变量的值才能被导入,从而避免全部内容都被导入了)。 -
包
将多个模块放在同一个文件夹下,并在这个文件夹下创建一个__init__.py的文件,那么这个文件夹就被称为包,文件夹名称为包名。
__init__.py文件主要用于控制包中模块的导入,在导入包时会执行文件中的内容
GIL
全局解释器锁(global interpreter lock);
python代码的执行时由Python虚拟机(也叫解释器主循环)来控制;
考虑到在任意时刻,只有一个线程在解释器中运行,因此对python虚拟机的访问又由全局解释锁来控制的;
在多线程环境中,python虚拟机运行步骤:
(1)获取GIL;
(2)切换到一个线程运行;
(3)运行(指定数量的字节码,或者线程主动让出控制(可以调用time.sleep(0)把线程设置为睡眠状态));
(4)解锁GIL,另一个线程重复以上步骤;
python内存回收机制和内存管理
- 垃圾回收
python不像c++、jave等语言需要提前声明变量类型才能对变量赋值;
对于python而言,变量的类型和内存都是在运行时确定的,因此称python为动态语言; - 引用计数
每一个对象,对维护一个指向该对象的引用计数;当变量被绑到对象时,该对象的引用计数为1(某些其他的操作会导致该引用计数增加,例如赋值给另外对象,传参,对象作为元素存储到容器),当引用计数为零时,该对象被回收(a = 1 a = 2 两个a的id不同,说明当执行a = 2的语句时,之前的a的对象能回收了,现在的a是新对象); - 内存机制
python的内存机制呈现金字塔状;
0层是c的malloc和free函数进行内存的分配和释放;
1层2层是内存池(256字节);
3层(最上层)由我们对python对象进行操作;
所以python在使用内存时,如果申请的内存大于256字节,直接使用malloc,否则使用自己的内存管理系统(内存池);
线程理解
python效率低下的原因
解释性语言、全局锁(假线程)
迭代器、生成器、装饰器
-
迭代器
迭代时访问集合元素的一种非常强大的方式。迭代器可以记住遍历位置,不会对例如列表这样的数据容器一次性全部生成,而是等到用的时候才会去生成。我们也可以创建一个可迭代的对象:任何对象只要实现了next方法和iter方法,就能很轻易的使用for循环遍历,那么它就是一个可迭代的对象。
如果要自定义实现一个迭代器,则类中必须实现以下两个方法:
1.__next(self):返回容器的下一个元素,在没有后续元素时,next()会抛出一个StopIteration异常;
2.__iter(self):该方法返回一个迭代器(iterator)。class Test: def __init__(self): self.__date=[] #==> list_t = [] self.__step = 0 def __next__(self): if self.__step <= 0: raise StopIteration self.__step -= 1 #返回下一个元素 return self.__date[self.__step] def __iter__(self): #实例对象本身就是迭代器对象,因此直接返回 self 即可 return self #添加元素 def __setitem__(self,key,value): self.__date.insert(key,value) self.__step += 1 t_list = Test() t_list[0]='jibu' t_list[1]='zhangsan' for i in t_list: print (i)
-
生成器
生成器是保存了一套生成数值的算法,并且没有让这个算法立即执行,而是我们什么调用它,它什么时候计算一个新的值,并返回。以 list 容器为例,在使用该容器迭代一组数据时,必须事先将所有数据存储到容器中,才能开始迭代;而生成器却不同,它可以实现在迭代的同时生成元素。优点:如果想要得到庞大的数据,又不想浪费空间(少占用空间),可以使用生成器;
创建生成器的两种方法:
(1)将列表表达式外面的[ ]修改成( );
(2)函数中使用关键字yield,下一次执行时,从yield的下一条语句开始执行;
生成器的使用:
1.使用对象的next函数obj.__ next __(),或是内置的next方法next(obj)
2.send函数,obj.send(x) 使用send可以强行改变上一次赋值,例如a = yield 5 ,运行到该语句直接返回5,a不会被赋值,但是如果使用的是send(10)的函数,那么下一次执行时,会给a 赋值 10,然后继续执行;def inf_N(): num = 1 while num <= 100: temp = yield num # 执行顺序是: #(1)yield num将num返回出去; #(2)将"yield num"这个个表达式的值交给变量temp。 # 但是num已经被yield返回出去了,所以交给temp的只能是None了。 # yield与return一样会将num返回出去,但不是像return一样结束函数, # 而是会卡在这里不执行,直到下一次使用next()方法唤醒。 num += 1 print(temp) print("数据已经生成并拿走完毕!") return None if __name__ == '__main__': inf_N_gennerate = inf_N() while True: time.sleep(0.5) value = next(inf_N_gennerate) print(value) inf_N_gennerate.send(100) # 会打印1 3 5 7 9是因为next和send都会唤醒生成器
-
装饰器
可以让其他函数在不需要做任何代码修改的前提下增加额外功能;
实质是采用闭包的思想来封装需要增加额外功能的函数;
# 为函数添加一个统计运行时长的功能
import time
import threading
def how_much_time(func):
def inner():
t_start = time.time()
func()
t_end = time.time()
print("一共花费了{0}秒时间".format(t_end - t_start, ))
return inner
@how_much_time
# @how_much_time等价于sleep_5s = how_much_time(sleep_5s)
def sleep_5s():
time.sleep(5)
print("%d秒结束了" % (5,))
@how_much_time
def sleep_6s():
time.sleep(6)
print("%d秒结束了" % (6,))
t1 = threading.Thread(target=sleep_5s)
t2 = threading.Thread(target=sleep_6s)
t1.start()
t2.start()
# 5秒结束了
# 一共花费了5.014161109924316秒时间
# 6秒结束了
# 一共花费了6.011810302734375秒时间
python模块的安装
-
pip安装
使用pip install 安装时,安装模块的包一般存放在%PYTHON%/Lib/site-packages下(分为module文件夹和module-xx.xx.dist.info文件夹),生成的可执行文件一般存放在%PYTHON%/Scripts下 -
源码安装
执行python setup.py install -
python二进制包
二进制包有两种常见的格式:egg(xx.egg)和wheel( xx.whl)