1. PEP8 编码规范,以及开发中的一些惯例和建议
- 代码编排:
- 缩进4个空格,禁止空格与tab混用
- 行长80:防止单行逻辑过于复杂
- import:
- 不要使用
from xxx import *
- 顺序
(1)标准库
(2)第三方库
(3)自定义库 - 单行不要import多个库
- 模块内用不到的不要去import
- 空格:
: , ;
后面跟一个空格·,前面无空格- 二元操作符前后各一个空格
- 适当添加空行:
- 函数间:顶级函数间空两行,类的方法之间空1行
- 函数内:同一函数内的逻辑之间空一行
- 文件结尾:留一个空行(Unix中\n是文件的结尾符)
- 注释:
- 忌:逐行添加注释,没有一个注释
- 行内注释:单行逻辑国语复杂是添加
- 块注释:一段逻辑开始时添加
- 引入外来算法或者配置时须在注释中添加连接,标明出处。
- 函数和类尽可能添加
docstring
- 命名:
- 除非在lambda函数中,否则不要用单字母的变量名
- 包名、模块名、函数名、方法名全部使用小写,单词间用下划线连接
- 类名、异常名使用CapWords(首字母大写)
- 全局变量尽量使用大写
- 字符串拼接:
- 尽量使用join方式,速度快,内存消耗小
注:自定义的变量名、函数名不要与标准库的名字冲突
练习1
规范这段代码
import sys
import os
from django.conf import settings
mod = 0xffffff
def foo(a,b=123):
c = {'x':111,'y':222}
d = [1,3,6]
return a,b,c
def bar(x):
if x % 2 == 0:
return True
*和**的使用
#函数定义
def foo(*args,**kwargs):
pass
#参数传递
def foo(x,y,z,a,b):
print(x)
print(y)
print(z)
print(a)
print(b)
lst = [1,2,3]
dic = {'a':22,'b':77}
foo(*lst,**dic)
import * 语法
#文件 xyz.py
_all_ = ('a','b','_d')
a = 123
_b = 456
c = 'hdwukg'
_d = [1,12,3,4,5]
e = (9,8,7,5,4)
#文件abc.py
from xyz import *
print(a)
print(_b)
print(c)
print(-d)
print(e)
强制命名参数
def foo(a,*,b,c=123):
pass
2.装饰器
#最简装饰器
def deco(func):
def sum(*args,**kwargs):
return func(*args,**kwargs)
return sum
@deco
def A(num1,num2):
print(num1 ** num2)
#带参数的装饰器
def deco(n):
def wrap1(func):
def wrap2(*args,**kwargs):
return wrap2
return wrap1
#调用过程
wrap1 = deco(n)
wrap2 = wrap1(foo)
foo = wrap2
foo()
#单行形式
check_res(30)(foo)(4,8)
3.函数闭包
函数闭包:引用了自由变量的函数即是一个闭包,这个被引用的自由变量和这个函数一同存在,即使已经离开了它创造的环境也不例外。
def foo():
l = []
def bar(i):
l.append(i)
return l
f1 = foo()
f2 = foo()
f1(1)
f2(2)
f3(3)
4.进程和线程
概念
- 进程就是操作系统中执行的一个程序,操作系统以进程为单位分配存储空间,每个进程都有自己的地址空间、数据栈以及其他用于跟踪进程执行的辅助数据,操作系统管理所有进程的执行,为它们合理的分配资源。
- 一个进程还可以拥有多个并发的执行线索,简单的说就是拥有多个可以获得CPU调度的执行单元,这就是所谓的线程。
Python中的多进程
如果程序中的代码只能按顺序一点点的往下执行,那么即使执行两个毫不相关的下载任务,也需要先等待一个文件下载完成后才能开始下一个下载任务,很显然这并不合理也没有效率。
import multiprocessing
import os
def A(name):
print(os.getpid())
print(name)
if __name__ == "__main__":
# 创建进程
p1 = multiprocessing.Process(target=A,args=(lyt1,))
p2 = multiprocessing.Process(target=A,args=(lyt2,))
p1.start() # 启动进程
p2.start()
p1.join()
p2.join()
print('Ok')
Python中的多线程
在Python早期的版本中就引入了thread模块(现在名为_thread)来实现多线程编程,然而该模块过于底层,而且很多功能都没有提供,因此目前的多线程开发我们推荐使用threading模块,该模块对多线程编程提供了更好的面向对象的封装。
练习2
#登录网页
import time
TIME1 = 0
TIME2 = 0
def check_ip(func):
def warp(*args,**kwargs):
if round(abs(TIME2-TIME1),3) <0.5:
print('404')
else:
return func(*args,**kwargs)
return warp
@check_ip
def A(ip):
print("进入网页成功")
#模拟请求
for _ in range(50):
ip = '127.0.0.1'
TIME1 = time.time()
A(ip)
TIME2 = time.time()
time.sleep(1)
#带参数的装饰器
#流氓验证码:
# 在使用装饰器的情况下,无论输入什么验证码都会返回验证码错误,
#如果不使用,该正确就打印正确
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) # 不加装饰器验证码一直返回错误
def A(n1,n2):
if n1 == n2:
print("验证码正确")
else:
print("验证码错误")
num = random.randrange(1000,9999)
print('验证码是:%d'%num)
num2 = int(input("请输入验证码>>>"))
A(n1=num,n2=num2)