python进阶
每日一酌:.比我差的人还没放弃,比我好的人仍在努力,我就更没资格说我无能为力!
PEP8编码规范
1,缩进4个空格,禁止空格与Tab混用。
2,import 不要使用from xxx import *。
顺序是 标准库
第三方库
自定义库
3,单行不要 import 多个库。
4,模块内用不到的不要去 import。
5,空格 (:,;)后面跟一个空格,前面无空格(行尾分号无空格)。
6,当 = 用于指示关键字参数或默认参数值时,不要再其两侧使用空行。
7,适当添加空行。
8,注释 忌:逐行添加注释,没有一个注释。
9,命名 除非在lambda函数中,否则不要用单字母的变量名。
包名,模块名,函数名,方法名全部使用小写,单词间用下划线连接。
全局变量尽量使用大写。
字符串拼接尽量使用 join方式,速度快,内存消耗小。
装饰器
讲 Python 装饰器前,我想先举个例子,虽有点污,但跟装饰器这个话题很贴切。
每个人都有的内裤主要功能是用来遮羞,但是到了冬天它没法为我们防风御寒,咋办?我们想到的一个办法就是把内裤改造一下,让它变得更厚更长,这样一来,它不仅有遮羞功能,还能提供保暖,不过有个问题,这个内裤被我们改造成了长裤后,虽然还有遮羞功能,但本质上它不再是一条真正的内裤了。于是聪明的人们发明长裤,在不影响内裤的前提下,直接把长裤套在了内裤外面,这样内裤还是内裤,有了长裤后宝宝再也不冷了。装饰器就像我们这里说的长裤,在不影响内裤作用的前提下,给我们的身子提供了保暖的功效。
简单的装饰器
def user(func):
#这里的func就相当与foo()函数
def warp():
print('i am warp')
return func() # 把 foo 当做参数传递进来时,执行func()就相当于执行foo()
return warp #warp()函数
@user
def foo():
print('i am foo')
foo() # 执行foo()就相当于执行 warp()
#装饰器逻辑:从foo()函数开始 --》@user --》func--》return warp --》print('i am warp') --》
# 返回func()函数就是返回print('i am foo')
带参数的装饰器
def tyler(leve):
def user(func):
def warp(*args,**kwargs):
if leve == "warn":
print('i am warp is warn')
elif leve == 'info':
print('i am warp is info')
return func(*args,**kwargs) #返回不定长参数,kwargs必须放在后面,因为是带变量名赋值
return warp
return user
@tyler(leve='info') #在这可以修改leve的参数,在走装饰器
def foo(12,name='foo'):
print('i am %sage'%name)
foo()
练习
无敌验证码,不管怎么输入验证码都显示验证码错误
import random
def deco2(parms):
def deco(func):
def warp(*args,**kwargs):
if parms :
kwargs['n1'] = -1
return func(*args,**kwargs)
return warp
return deco
@deco2(True) #这里要是true 则会走warp里的if 将n1 的值改为 -1
#这样只会输出验证码错误,改为false就不会走warp里的if,,,程序正常运行
def A(n1,n2):
if n1 == n2:
print('验证码正确')
else:
print('验证码错误')
num = random.randint(1000,9999)
print('验证码是%d'%num)
num2 = int(input('>>'))
A(n1=num,n2=num2)
练习二
def deco(func):
def warp(n,n1):
sum_ = n + n1
return func(sum_,n1) #将sum_作为参数传给func(),func()就是A(name,name1)。
#所以name参数的值就是sum_
return warp
@deco
def A(name,name1):
print(name)
A(10,12)
函数闭包(Function Closure)
介绍闭包前有必要先介绍一些背景知识,诸如嵌套函数、变量的作用域等概念
作用域:作用域是程序运行时变量可被访问的范围,定义在函数内的变量是局部变量,局部变量的作 用范围只能是函数内部范围内,它不能在函数外引用
嵌套函数: 就是一层函数套一层函数
闭包
闭包,顾名思义,就是一个封闭的包裹,里面包裹着自由变量,就像在类里面定义的属性值一样,自由变量的可见范围随同包裹,哪里可以访问到这个包裹,哪里就可以访问到这个自由变量。
为什么要使用闭包
闭包避免了使用全局变量,此外,闭包允许将函数与其所操作的某些数据(环境)关连起来。这一点与面向对象编程是非常类似的,在面对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。
例子
def adder():
l = []
def bar(i):
l.append(i)
return l
return bar
f1 = adder()
f2 = adder()
print(f1(1)) #[1]
print(f2(2)) #[2]
print(f1(2)) #[1, 2]
作用域
声明全局变量:global
声明非本层的 局部变量 : nonlocal
查看全局变量:global()
查看局部变量:locals()
进程
进程就是操作系统中执行的一个程序,操作系统以进程为单位分配存储空间,每个进程都有自己的地址空间、数据栈以及其他用于跟踪进程执行的辅助数据,操作系统管理所有进程的执行,为它们合理的分配资源。
并发与并行
举个例子
停车场,你正在倒车入库,突然由来了一辆车把你的车位给抢了,这是并发。
并行就是有两的车位,你倒你的,他倒他的,互不干扰。
例子
import multiprocessing
def A():
print('name')
if __name__ == "__main__":
#创建进程
p = multiprocessing.Process(target=A,args=())
p.start() #启动线程
p.join()
print('asd')
#结果 name 程序本身就是一个主进程,所以先走A()在走子进程p
# asd
多进程
from multiprocessing import Process
from os import getpid
from random import randint
from time import time, sleep
def download_task(filename):
print('启动下载进程,进程号[%d].' % getpid())
print('开始下载%s...' % filename)
time_to_download = randint(5, 10)
sleep(time_to_download)
print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))
def main():
start = time()
p1 = Process(target=download_task, args=('Python从入门到住院.pdf', ))
p1.start()
p2 = Process(target=download_task, args=('Peking Hot.avi', ))
p2.start()
p1.join()
p2.join()
end = time()
print('总共耗费了%.2f秒.' % (end - start))
if __name__ == '__main__':
main()