Python编程经验
代码结构
工作目录
- 为每个用户,每项任务创建单独的文件夹
def mkuserdir(user):
if not os.path.isdir(user):
print(B("[*]Mkdir %s" % user))
os.mkdir(user)
else:
print(B("[*]Dir %s already exists" % user))
全局变量
- 设置全局变量FILTER列表,过滤时间以及关键字,在业务函数内部判断
- 设置全局布尔变量
调试信息
-
在函数入口处、循环处、判断处、IO处、异常处打印调试信息
-
字符串颜色处理
#红色:报错
def R(message):
return "\033[1;91m{}\033[0;m".format(message)
#绿色:成功
def G(message):
return "\033[1;92m{}\033[0;m".format(message)
#黄色:警告
def Y(message):
return "\033[1;93m{}\033[0;m".format(message)
#蓝色:提示
def B(message):
return "\033[1;94m{}\033[0;m".format(message)
- 打印格式
#提示
print(B("[*]Getting outbox in the email: %s" % user))
#报错
print(R("[-]Get mail fail, time cost: %.2fs" % (time)))
#成功
print(G("[+]Get mail successfully, time cost: %.2fs" % (time)))
- python2/3 print不报错
#用比当前版本的 python 更新的版本的print函数
from __future__ import print_function
异常处理
- 对容易出错的代码(IO/查找/转换)的代码用try包起来
- try里还可以再用try捕捉更细节的错误
- 定义报错函数PrintException,在except处调用
- 使用sys.exc_info获取错误信息
def PrintException():
exc_type, exc_obj, tb = sys.exc_info()
f = tb.tb_frame
lineno = tb.tb_lineno
filename = f.f_code.co_filename
linecache.checkcache(filename)
line = linecache.getline(filename, lineno, f.f_globals)
print(R('EXCEPTION IN (LINE {} "{}"): {}'.format(lineno, line.strip(), exc_obj)))
- 也可使用traceback.printexc()
from traceback import print_exc
try:
account = getAccount(user, passwd)
except Exception,e:
traceback.print_exc()
尝试次数
- 设置尝试次数,超出后就返回错误
tries1 = 0
while tries1<3:
try:
account = getAccount(user, passwd)
break
except Exception as e:
PrintException()
tries1 += 1
time.sleep(20)
if tries1 == 3:
return False
化简结构
-
对列表尽量使用生成式
-
一句话IO
mids = open(os.path.join(user, "mid.txt")).read().split()
日志
- 编写专门的log函数,log/log2file,将成功或者失败信息写入日志
def log(user, text):
print(B(text))
with open(os.path.join(user, "log.txt"), "a") as f:
f.write(text+"\n")
哈希和ID
- 将哈希或者ID保存到全局列表或者写到文件中,避免重复操作对象
def message_id(user, item, oper):
if oper == 'w':
try:
with open(os.path.join(user, "mid.txt"), "a") as f:
f.write(item.message_id+"\n")
return True
except:
return False
elif oper == 'q':
try:
mids = open(os.path.join(user, "mid.txt")).read().split()
if item.message_id in mids:
return True
else:
return False
except:
return False
函数
-
按照包含关系分层,按照独立功能分块
-
入口判断、值获取、业务处理
-
每个函数调用都设置返回值,根据返回值判断是否成功,是否进行下一步
-
连接函数:用函数返回对象,比如account
-
业务函数:处理独立业务逻辑
第三方库
exchangelib
- 屏蔽https证书警告
import urllib3
urllib3.disable_warnings(InsecureRequestWarning)
- 忽略ssl错误
from exchangelib.protocol import BaseProtocol
from exchangelib.protocol import NoVerifyHTTPAdapter
BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter
- 加入请求头
BaseProtocol.USERAGENT = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36"
- 传输适配器:用来为HTTP\HTTPS服务自定义交互方法
import requests.adapters
字符串处理
replace
fp.write(item.body.replace("\\r\\n", "\n"))
strip
line.strip()
split
address.split("@")[0]
join
symbol.join(seq) #用symbol符号将seq序列中的元素连接到一起
格式化
- 原生格式化
path = "%s_%s_%s" % (address.split("@")[0], line.split()[0], item)
- format格式化
print("[*] Found {} mails, {} unread".format(account.inbox.total_count, account.inbox.unread_count))
列表处理
打包函数
- 用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象
data = pd.read_excel('GDP.xlsx')
province = list(data["province"])
gdp = list(data["2019_gdp"])
list = [list(z) for z in zip(province,gdp)]