In [10]: sum(range(101)) Out[10]: 5050
sum() 方法对系列进行求和计算。sum函数的参数必须是可迭代的对象html
range() 函数可建立一个整数列表,通常用在 for 循环中。python
利用 global 修改全局变量git
os:提供了很多与操做系统相关联的函数
sys: 一般用于命令行参数程序员
time:时间模块
re: 正则匹配
math: 数学运算
datetime:处理日期时间web
字典删除键的方法有pop和del两个算法
pop和del方法删除字典的键,若是键不存在都会报错json
update方法用来合并字典api
GIL 是 python 的全局解释器锁,同一进程中假若有多个线程运行,一个线程在运行 python 程序的时候会霸占 python 解释器(加了一把锁即 GIL),使该进程内的其余线程没法运行,等该线程运行完后其余线程才能运行。若是线程运行过程当中遇到耗时操做,则解释器锁解开,使其余线程运行。因此在多线程中,线程的运行还是有前后顺序的,并非同时进行。多进程中由于每一个进程都能被系统分配资源,至关于每一个进程有了一个 python 解释器,因此多进程能够实现多个进程的同时运行,缺点是进程系统资源开销大。数组
os.path 主要是用于对系统路径文件的操做。浏览器
sys.path 主要是对 Python 解释器的系统环境参数的操做(动态的改变 Python 解释器搜索路径)。
在 Python 中,模块是搭建程序的一种方式。每个 Python 代码文件都是一个模块,并能够引用其余的模块,好比对象和属性。
一个包含许多 Python 代码的文件夹是一个包。一个包能够包含模块和子文件夹。
计算机不能直接理解高级语言,只能直接理解机器语言,因此必需要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序。
解释性语言在运行程序的时候才会进行翻译。
编译型语言写的程序在执行以前,须要一个专门的编译过程,把程序编译成机器语言(可执行文件)。编译型语言写的程序在执行以前,须要一个专门的编译过程,把程序编译成机器语言(可执行文件)。
一、使用多进程,充分利用机器的多核性能
二、对于性能影响较大的部分代码,可使用 C 或 C++编写
三、对于 IO 阻塞形成的性能影响,可使用 IO 多路复用来解决
四、尽可能使用 Python 的内建函数
五、尽可能使用局部变量
字典是一种数据结构,json 是一种数据的表现形式,字典的 key 值只要是能 hash 的就行,json 的必须是字符串。json的key必须是双引号,python的字典不须要,单引号也能够
可变不可变指的是内存中的值是否能够被改变,不可变类型指的是对象所在内存块里面的值不能够改变,有数值、字符串、元组;可变类型则是能够改变,主要有列表、字典。
print("hello world!"[::-1])
t_str = "k:1|k1:2|k2:3|k3:4" t_dict = {i.split(":")[0]:int(i.split(":")[1]) for i in t_str.split("|")} print(t_dict) # 输出结果 {'k1': 2, 'k': 1, 'k2': 3, 'k3': 4}
print([i*10 for i in range(10)]) # 输出结果 [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
答:random 模块
随机整数:random.randint(a,b):返回随机整数 x,a<=x<=b
random.randrange(start,stop,[,step]):返回一个范围在(start,stop,step)之间的随机整数,不包括结束值。
随机实数:random.random( ):返回 0 到 1 之间的浮点数
random.uniform(a,b):返回指定范围内的浮点数。
单引号和双引号是等效的,若是要换行,须要符号(\),三引号则能够直接换行,而且能够包含注释
1. [1,2,3,4,5,6,7,8,9] 2. [1,2,3,4,5,6] 3. [3,4,5,6] 4. [9] 5. [1,3,5,7,9]
解决方法
print([i for i in t_list[1:]]) # 输出结果 [1, 2, 3, 4, 5, 6, 7, 8, 9] print([i for i in t_list[1:7]]) # 输出结果 [1, 2, 3, 4, 5, 6] print([i for i in t_list[3:7]]) # 输出结果 [3, 4, 5, 6] print([i for i in t_list[9:]]) # 输出结果 [9] print([i for i in t_list[1::2]]) # 输出结果 [1, 3, 5, 7, 9]
类方法:是类对象的方法,在定义时须要在上方使用@classmethod进行装饰,形参为 cls,表示类对象,类对象和实例对象均可调用;
类实例方法:是类实例化对象的方法,只有实例对象能够调用,形参为self,指代对象自己;
静态方法:是一个任意函数,在其上方使用@staticmethod进行装饰,能够用对象直接调用,静态方法实际上跟该类没有太大关系。
能够到这里查看具体内容https://www.cnblogs.com/geaozhang/p/7111961.html
引用计数:
引用计数是一种很是高效的内存管理手段,当一个python对象被引用时,它的引用计数增长1,当它再也不被一个变量引用时则引用计数减1,当它的引用计数等于0时对象被删除
垃圾回收:
当Python的某个对象的引用计数降为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾。好比某个新建对象,被分配给某个引用,对象的引用计数变为1。若是引用被删除,对象的引用计数为0,那么该对象就能够被垃圾回收。
内存池:
Python 在运行期间会大量地执行 malloc 和 free 的操做,频繁地在用户态和核心态之间进行切换,这将严重影响 Python 的执行效率。为了加速 Python 的执行效率,Python 引入了一个内存池机制,用于管理对小块内存的申请和释放。
Python 内部默认的小块内存与大块内存的分界点定在 256 个字节,当申请的内存小于 256 字节时,PyObject_Malloc 会在内存池中申请内存;当申请的内存大于 256 字节时,PyObject_Malloc 的行为将蜕化为 malloc 的行为。固然,经过修改 Python 源代码,咱们能够改变这个默认值,从而改变 Python 的默认内存管理行为。
1.手动垃圾回收
2.调高垃圾回收阈值
3.避免循环引用(手动解循环引用和使用弱引用)
指因为疏忽或错误形成程序未能释放已经再也不使用的内存的状况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,于是形成了内存的浪费。致使程序运行速度减慢甚至系统崩溃等严重后果。
有__del__() 函数的对象间的循环引用是致使内存泄漏的主凶。
不使用一个对象时使用:del object 来删除一个对象的引用计数就能够有效防止内存泄漏问题。经过 Python 扩展模块 gc 来查看不能回收的对象的详细信息。
能够经过 sys.getrefcount(obj) 来获取对象的引用计数,并根据返回值是否为 0 来判断是否内存泄漏。
Python 的参数传递有:位置参数、默认参数、可变参数、关键字参数。
函数的传值究竟是值传递仍是引用传递,要分状况:
不可变参数用值传递:
像整数和字符串这样的不可变对象,是经过拷贝进行传递的,由于你不管如何都不可能在原处改变不可变对象
可变参数是引用传递的:
好比像列表,字典这样的对象是经过引用传递、和 C 语言里面的用指针传递数组很类似,可变对象能在函数内部改变。
缺省参数指在调用函数的时候没有传入参数的状况下,调用默认的参数,在调用函数的同时赋值时, 所传入的参数会替代默认参数。
*args 是不定长参数,他能够表示输入参数是不肯定的,能够是任意多个。
**kwargs 是关键字参数,赋值的时候是以键 = 值的方式,参数是能够任意多对在定义函数的时候不肯定会有多少参数会传入时,就可使用两个参数。
递归的终止条件通常定义在递归函数内部,在递归调用前要作一个条件判断,根据判断的结果选择是继续调用自身,仍是 return;返回终止递归。
终止的条件:
判断递归的次数是否达到某一限定值
判断运算的结果是否达到某个范围等,根据设计的目的来选择
一个简单的递归函数的例子
def p_num(num): if num > 0: print(num) p_num(num - 1) p_num(4) # 输出结果 4 3 2 1
python的数据类型有
int 整型、bool 布尔、str 字符串、list 列表、tuple 元组、dict 字典、float 浮点型小数
print(dir("a"))的输出是
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
输出字符串‘a’的内建方法;
class Person(): def __init__(self): self.name = "hahah" self.age = 24 def eat(self): print("正在吃饭") p1 = Person()
hasattr(object, name)函数:
判断一个对象里面是否有name 属性或者name 方法,返回bool 值,有name 属性(方法)返回True, 不然返回 False。
注意:name 要使用引号括起来
print(hasattr(p1, "eat")) # 输出结果 True print(hasattr(p1, "name")) # 输出结果 True print(hasattr(p1, "age")) # 输出结果 True # 输入一个不存在的属性名或者方法名,就会返回False print(hasattr(p1, "aname")) # 输出结果 False print(hasattr(p1, "aage")) # 输出结果 False print(hasattr(p1, "aeat")) # 输出结果 False
getattr(object, name[,default]) 函数:
获取对象 object 的属性或者方法,若是存在则打印出来,若是不存在,打印默认值,默认值可选。注意:若是返回的是对象的方法,则打印结果是:方法的内存地址,若是须要运行这个方法,能够在后面添加括号()。
print(getattr(p1,"name")) # 输出name属性的值"hahah" print(getattr(p1,"age")) # 输出age属性的值24 # 若是获取的是方法,返回的就是这个方法的内存地址 print(getattr(p1,"eat")) # <bound method Person.eat of <__main__.Person object at 0x7fd87e2d29e8>> # 若是获取的方法或者属性不存在,会报错 print(getattr(p1,"nameasdasd")) # Traceback (most recent call last): # File "/home/fengwr/Desktop/code/spider/lx.py", line 40, in <module> # print(getattr(p1,"nameasdasd")) # AttributeError: 'Person' object has no attribute 'nameasdasd' # 若是属性或方法不存在,设置默认值 print(getattr(p1,"nameasdasd", "默认内容")) # 输出"默认内容"
setattr(object,name,values)函数:
给对象的属性赋值,若属性不存在,先建立再赋值
setattr(p1, "height", 178.56) print(p1.height) # 输出结果 178.56
在函数内部再定义一个函数,而且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包。
is 判断的是 a 对象是否就是 b 对象,是经过 id 来判断的。
==判断的是 a 对象的值是否和 b 对象的值相等,是经过 值 来判断的。
以两个下划线开头的属性和方法称为私有属性和私有方法,可是也可经过特定的方法来访问,因此python中是伪私有属性和伪私有方法
访问私有属性和私有方法
_类名__属性名
_类名__方法名()
class Demo1(): __name = "小明" @property def name(self): return self.__name if __name__ == '__main__': d1 = Demo1() print(d1.name) # 输出小明 d1.name = "小红" #报错 print(d1.name)
会报以下错误
Traceback (most recent call last): File "C:/Users/fengwr/Desktop/demo/lx01.py", line 11, in <module> d1.name = "小红" AttributeError: can't set attribute
不能设置属性。
就是用property装饰器把方法变成了类的属性
这样就实现了只读属性
面向对象是相对于面向过程而言的。面向过程语言是一种基于功能分析的、以算法为中心的程序设计方法;而面向对象是一种基于结构分析的、以数据为中心的程序设计思想。在面向对象语言中有一个有很重要东西,叫作类。
面向对象有三大特性:封装、继承、多态。
match()函数只检测 RE 是否是在 string 的开始位置匹配,search()会扫描整个 string 查找匹配;
也就是说 match()只有在 0 位置匹配成功的话才有返回,若是不是开始位置匹配成功的话,match()就返回 none。
import re a = "hello world" print(re.match("hell", a)) # 输出<_sre.SRE_Match object; span=(0, 4), match='hell'> print(re.match("ell", a)) # 输出 None print(re.search("ell", a)) # 输出<_sre.SRE_Match object; span=(1, 4), match='ell'>
import re a = "hello world" # re.findall(r'目的字符串', 原有字符串),返回一个列表 print(re.findall(r'llo', a)) # 输出['llo'] # re.sub(r'要替换的原字符', '要替换的新字符', '原始字符串'),返回字符串 print(re.sub(r'hello', 'goodnight', a)) # 输出goodnight world
<.*>是贪婪匹配,会从第一个“ <”开始匹配,直到最后一个“ >”中间全部的字符都会匹配到,中间可能会包含“ <>”。
<.*?>是非贪婪匹配,从第一个“ <”开始日后,遇到第一个“ >”结束匹配,这中间的字符串都会匹配到,可是不会有“ <>”。
进程:一个运行的程序(代码)就是一个进程,没有运行的代码叫程序,进程是系统资源分配的最小单位,进程拥有本身独立的内存空间,因此进程间数据不共享,开销大。
线程: 调度执行的最小单位,也叫执行路径,不能独立存在,依赖进程存在一个进程至少有一个线程,叫主线程,而多个线程共享内存(数据共享,共享全局变量),从而极大地提升了程序的运行效率。
协程:是一种用户态的轻量级线程,协程的调度彻底由用户控制。协程拥有本身的寄存器上下文和栈。 协程调度切换时,将寄存器上下文和栈保存到其余地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操做栈则基本没有内核切换的开销,能够不加锁的访问全局变量,因此上下文的切换很是快。
线程是非独立的,同一个进程里线程是数据共享的,当各个线程访问数据资源时会出现竞争状态即:数据几乎同步会被多个线程占用,形成数据混乱 ,即所谓的线程不安全
那么怎么解决多线程竞争问题?-- 锁。
锁的好处:
确保了某段关键代码(共享数据资源)只能由一个线程从头至尾完整地执行能解决多线程资源竞争下的原子操做问题。
锁的坏处:
阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地降低了锁的致命问题:死锁。
若干子线程在系统资源竞争时,都在等待对方对某部分资源解除占用状态,结果是谁也不肯先解锁,互相干等着,程序没法执行下去,这就是死锁。
做用:限制多线程同时执行,保证同一时间只有一个线程执行,因此 cpython 里的多线程实际上是伪多线程!
因此 Python 里经常使用协程技术来代替多线程,协程是一种更轻量级的线程,
进程和线程的切换时由系统决定,而协程由咱们程序员本身决定,而模块 gevent 下切换是遇到了耗时操做才会切换。
三者的关系:进程里有线程,线程里有协程。
每一个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
同一个进程中的多线程之间是共享系统资源的,多个线程同时对一个对象进行操做,一个线程操做还没有结束,另外一个线程已经对其进行操做,致使最终结果出现错误,此时须要对被操做对象添加互斥锁,保证每一个线程对该对象的操做都获得正确的结果。
同步:多个任务之间有前后顺序执行,一个执行完下个才能执行。
异步:多个任务之间没有前后顺序,能够同时执行有时候一个任务可能要在必要的时候获取另外一个
同时执行的任务的结果,这个就叫回调!
阻塞:若是卡住了调用者,调用者不能继续往下执行,就是说调用者阻塞了。
非阻塞:若是不会卡住,能够继续执行,就是说非阻塞的。
同步异步相对于多任务而言,阻塞非阻塞相对于代码执行而言。
孤儿进程:父进程退出,子进程还在运行的这些子进程都是孤儿进程,孤儿进程将被 init 进程(进程号为 1)所收养,并由 init 进程对它们完成状态收集工做。
僵尸进程:进程使用 fork 建立子进程,若是子进程退出,而父进程并无调用 wait 或 waitpid 获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中的这些进程是僵尸进程。
避免僵尸进程的方法:
1.fork 两次用孙子进程去完成子进程的任务;
2.用 wait()函数使父进程阻塞;
3.使用信号量,在 signal handler 中调用 waitpid,这样父进程不用阻塞。
多进程适合在 CPU 密集型操做(cpu 操做指令比较多,如位数多的浮点运算)。
多线程适合在 IO 密集型操做(读写数据操做较多的,好比爬虫)。
线程是并发,进程是并行;
进程之间相互独立,是系统分配资源的最小单位,同一个线程中的全部线程共享资源。
并行:同一时刻多个任务同时在运行。
并发:在同一时间间隔内多个任务都在运行,可是并不会在同一时刻同时运行,存在交替执行的状况。
实现并行的库有:multiprocessing
实现并发的库有:threading
程序须要执行较多的读写、请求和回复任务的须要大量的 IO 操做,IO 密集型操做使用并发更好。
CPU 运算量大的程序程序,使用并行会更好。
IO 密集型:系统运做,大部分的情况是 CPU 在等 I/O (硬盘/内存)的读/写。
CPU 密集型:大部份时间用来作计算、逻辑判断等 CPU 动做的程序称之 CPU 密集型。
UDP 是面向无链接的通信协议,UDP 数据包括目的端口号和源端口号信息。
优势:UDP 速度快、操做简单、要求系统资源较少,因为通信不须要链接,能够实现广播发送
缺点:UDP 传送数据前并不与对方创建链接,对接收到的数据也不发送确认信号,发送端不知道数据是否会正确接收,也不重复发送,不可靠。
TCP 是面向链接的通信协议,经过三次握手创建链接,通信完成时四次挥手
优势:TCP 在数据传递时,有确认、窗口、重传、阻塞等控制机制,能保证数据正确性,较为可靠。
缺点:TCP 相对于 UDP 速度慢一点,要求系统资源较多。
先要解析出 baidu.com 对应的 ip 地址
GET 请求,请求的数据会附加在 URL 以后,以?分割 URL 和传输数据,多个参数用&链接。URL 的编码格式采用的是 ASCII 编码,而不是 uniclde,便是说全部的非 ASCII 字符都要编码以后再传输。
POST 请求:POST 请求会把请求的数据放置在 HTTP 请求包的包体中。上面的 item=bandsaw 就是实际的传输数据。
所以,GET 请求的数据会暴露在地址栏中,而 POST 请求则不会。传输数据的大小:
安全性:
历史记录的缘由,此时的用户名和密码就很容易被他人拿到了。除此以外,GET 请求提交的数据还可能会形成 Cross-site request frogery 攻击。
效率:GET 比 POST 效率高。
POST 请求的过程:
GET 请求的过程:
服务器返回 200 OK 响应
一、cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
二、cookie 不是很安全,别人能够分析存放在本地的 cookie 并进行 cookie 欺骗考虑到安全应当使用 session。
三、session 会在必定时间内保存在服务器上。当访问增多,会比较占用服务器的性能考虑到减轻服务器性能方面,应当使用 cookie。
四、单个 cookie 保存的数据不能超过 4K,不少浏览器都限制一个站点最多保存 20 个 cookie。
五、建议: 将登录信息等重要信息存放为 SESSION 其余信息若是须要保留,能够放在 cookie 中
三次握手过程:
1 首先客户端向服务端发送一个带有 SYN 标志,以及随机生成的序号 100(0 字节)的报文
2 服务端收到报文后返回一个报文(SYN200(0 字节),ACk1001(字节+1))给客户端
3 客户端再次发送带有 ACk 标志 201(字节+)序号的报文给服务端至此三次握手过程结束,客户端开始向服务端发送数据。
1 客户端向服务端发起请求:我想给你通讯,你准备好了么?
2 服务端收到请求后回应客户端:I'ok,你准备好了么
3 客户端礼貌的再次回一下客户端:准备就绪,我们开始通讯吧!
整个过程跟打电话的过程如出一辙:1 喂,你在吗 2 在,我说的你听获得不 3 恩,听获得(接下来请开始你的表演)
补充:SYN:请求询问,ACk:回复,回应。
四次挥手过程:
因为 TCP 链接是能够双向通讯的(全双工),所以每一个方向都必须单独进行关闭(这句话才是精辟,后面四个挥手过程都是其具体实现的语言描述)
四次挥手过程,客户端和服务端均可以先开始断开链接
1 客户端发送带有 fin 标识的报文给服务端,请求通讯关闭
2 服务端收到信息后,回复 ACK 答应关闭客户端通讯(链接)请求
3 服务端发送带有 fin 标识的报文给客户端,也请求关闭通讯
4 客户端回应 ack 给服务端,答应关闭服务端的通讯(链接)请求
HTTP 协议传输的数据都是未加密的,也就是明文的,所以使用 HTTP 协议传输隐私信息很是不安全,为了保证这些隐私数据能加密传输,因而网景公司设计了 SSL(Secure Sockets Layer)协议用于对 HTTP 协议传输的数据进行加密,从而就诞生了 HTTPS。简单来讲,HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,要比 http 协议安全。
HTTPS 和 HTTP 的区别主要以下:
一、https 协议须要到 ca 申请证书,通常免费证书较少,于是须要必定费用。
二、http 是超文本传输协议,信息是明文传输,https 则是具备安全性的 ssl 加密传输协议。
三、http 和 https 使用的是彻底不一样的链接方式,用的端口也不同,前者是 80,后者是 443。
四、http 的链接很简单,是无状态的;HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全。
Host (主机和端口号)
Connection (连接类型)
Upgrade-Insecure-Requests (升级为 HTTPS 请求)
User-Agent (浏览器名称)
Accept (传输文件类型)
Referer (页面跳转处)
Accept-Encoding(文件编解码格式)
Cookie (Cookie)
x-requested-with :XMLHttpRequest (是 Ajax 异步请求)
应用层,表示层,会话层,传输层,网络层,数据链路层,物理层
IP: 网络层
TCP/UDP: 传输层
HTTP、RTSP、FTP: 应用层协议
Python2 中使用 ASCII 码做为默认编码方式致使 string 有两种类型 str 和 unicode,Python3 只支持 unicode 的 string。
Python2 的缩进机制中,1 个 tab 和 8 个 space 是等价的,因此在缩进中能够同时容许 tab 和 space 在代码中共存。这种等价机制会致使部分 IDE 使用存在问题。Python3 中 1 个 tab 只能找另一个 tab 替代,所以 tab 和 space 共存会致使报错:TabError:inconsistent use of tabs and spaces in indentation.
1. print 语句被 Python3 废弃,统一使用 print 函数2. exec 语句被 python3 废弃,统一使用 exec 函数3. execfile 语句被 Python3 废弃,推荐使用 exec(open("./filename").read())4. 不相等操做符"<>"被 Python3 废弃,统一使用"!="5. long 整数类型被 Python3 废弃,统一使用 int6. xrange 函数被 Python3 废弃,统一使用 range,Python3 中 range 的机制也进行修改并提升了大数据集生成效率