li = [11,22,33,44]
def f1(arg):
arg.append(55)
#函数默认返回值None,函数参数传递的是引用
li = f1(li)print(li)
内置函数补充:
判断是否被调用
def f1():
pass
print(callable(f1))
ASCII码与数字转换
#数字转换为ASCII码
r = chr(65)
print(r)
#ASCII转换为数字
n = ord('a')
print(n)
随机验证码
import random
list_temp =[]
for i in range(10):
r = random.randrange(0,10)
if r == 2 or r == 4 or r == 9:
num = random.randrange(0, 10)
list_temp.append(str(num))
else:
temp = random.randrange(65, 91)
c = chr(temp)
list_temp.append(c)
result = "".join(list_temp)
print(result)
编译、执行
s = "print(123)"
#编译: single(单行), eval(表达式), exec(编译成和python一样)
#将字符串编译成python代码
r = compile(s, "<string>", "exec")
#exec执行python代码,没有返回值
exec(r)
#eval只执行表达式,有返回结果
box = "8 * 8"
ret = eval(box)
print(ret)
查看对象提供的功能和帮助
#dir()查看一个对象提供的功能
dir(dict)
#查看功能的具体使用,即源码
help(list)
计算商和余数
#共97条数据,每页显示10条,需要多少页?
n1, n2 = divmod(97,10)
#n1为商,n2位=为余数
print(n1, n2)
判断对象是否是类的实例
#对象:由类创建,对象是类的实例
a = "wang"
#判断对象是否是类的实例
r = isinstance(a, str)
print(r)
筛选符合条件的函数
list_filter = [21,22,33,44,5,66,777,88,9,0,89]
def f2(a):
if a > 22:
return True
#filter(函数,可迭代的对象),filter内部首先会循环第二个参数,将每一个循环元素取去执行第一个参数(即函数)ret = filter(f2, list_filer)print(list_filer)
filter内部操作
for item in 第二个参数:r = 第一个参数(item)if r:result(item)return result
将简单函数使用lambda表示
f1 = lambda a: a > 30
ret = f1(31)
print(ret) li = [11,22,33,44,55,66]
result = filter(lambda a: a > 33, li)
print(list(result))1
map()将返回值添加到结果中
#map(函数,可迭代的对象(可以for循环的内容))
# 将返回值添加到结果中
li = [11,22,33,44,55,66]
result = map(lambda a: a + 100, li)
print(list(result))
filter:如果函数返回True,将元素添加到结果中map:将函数返回值添加到结果中
globals()所有的全局变量
locals()所有的局部变量
NAME = 'wang' def show():
a = 123
print(locals())
print(globals())
show()
hash()用于字典的key保存
s = 'pssiacmaakmcasmcamcasomcwmclwmclw'
print(hash(s))
id()查看内存地址
iter()创建迭代器
len()查看长度
s = "哈哈"
b = bytes(s, encoding='utf-8')
#python3.*即可通过字符查看,也可以通过字节查看
#python2.7只能通过字节查看
print(len(b))
ss = "哈哈"
for a in ss:
print(a)
最大值、最小值、求和
#max(),min(),sum()
rr = max([11,22,33,44])
print(rr)
aa = min([11,22,33,44])
print(aa)
dd = sum([11,22,33,44])
print(dd)
object是所有类的父类
求指数
r6 = pow(2, 10)
print(r6)
四舍五入
r = round(4.6)
print(r)
进制转换
十进制转二进制bin()、十进制转十六进制hex()、十进制转八进制oct()、十进制转十进制int()
slice()切片、sort()排序、vars()查看变量
zip()混合列表中对应下标的元素组成元祖,元祖为新的列表中的元素
l1 = ['alex', 11, 22 ,33]
l2 = ['is', 11, 22, 33]
l3 = ['sb', 11, 22, 33] r = zip(l1, l2, l3)
temp = list(r)[0]
ret = ' '.join(temp)
print(ret)
反转
li = [11, 22, 33, 44, 'll']
li.reverse()或reverse(li)
将字符串转换为列表
s = "[11, 22, 33, 44]"
s = '{"k1":"v1"}'
print(type(s), s)
import json
n = json.loads(s) #将一个字符串转换成python的基本数据类型,注意:字符串形式的字典'{"k1":"v1"}'内部的字符串必须为双引号
print(type(n), n)
json
import jsondef json_conf(record):
dict_conf = json.loads(record)
backend = dict_conf['backend'] record_conf = "server %s %s weight %d maxconn %d" % (dict_conf['record']['server1'],
dict_conf['record']['server2'],
dict_conf['record']['weight'],
dict_conf['record']['maxconn']) print("处理完成后,backend is : %s ,record is : %s" % (backend, record_conf))
ha.conf文件信息
global
log 127.0.0.1 local2
daemon
maxconn 256
log 127.0.0.1 local2 info
defaults
log global
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
option dontlognull listen stats :8888
stats enable
stats uri /admin
stats auth admin:1234 frontend oldboy.org
bind 0.0.0.0:80
option httplog
option httpclose
option forwardfor
log global
acl www hdr_reg(host) -i www.oldboy.org
use_backend www.oldboy.org if www backend www.oldboy.org
server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000
server 100.1.7.29 100.1.7.39 weight 10 maxconn 300 backend buy.oldboy.org
server 100.1.7.90 100.1.7.90 weight 20 maxconn 3000
读取ha.conf配置文件,将与用户输入对应的行添加到列表中
def fetch(backend):
#print("backend is : %s" % backend)
#backend = “www.oldboy.org”
result = []
#打开配置文件
with open('ha.conf', 'r', encoding='utf-8') as f:
#设定跳出判断标记位
flag = False
#按行读取文件
for line in f:
#print("line is : %s" % line)
#匹配到backend行
if line.strip().startswith("backend") and line.strip() == "backend " + backend:
#print("line is : %s" % line)
flag = True
#匹配到backend后跳过这一行
continue
#flag = True时,配置文件中有两种情况:backend buy.oldboy.org和backend www.oldboy.org
#读完backend这一行后继续后面读又出现了backend,即读到这一句:backend buy.oldboy.org
if flag and line.strip().startswith("backend"):
flag = False
#终止
break
#匹配到backend且是一次匹配到backend,flag = True,backend www.oldboy.org,且去掉空字符串
if flag and line.strip():
#将"server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000"添加到结果列表中
result.append(line.strip()) return resultret = fetch("www.oldboy.org")
print(ret)
更新配置文件
def add(backend, record):
#先检查记录是否存在fetch()
record_list = fetch(backend)
#代码顺序,先易后难
if not record_list:
#backend不存在,需要新增backend和record,即把原文件全部写到新的文件中,然后在最后添加backend+record_list
with open('ha.conf', 'r') as old, open('new.conf', 'w') as new:
#读取一行旧的文件,写一行新的文件
for line in old:
new.write(line)
#将新增的部分添加到新文件末尾
#先加backend
new.write("\nbackend " + backend + "\n")
#后加server信息
new.write(" " * 8 + record + "\n")
else:
#backend存在
if record in record_list:
#backend存在,record也存在
import shutil
#复制原文件
shutil.copy("ha.conf", "new.conf")
else:
#backend存在,record不存在
#不存在record则将其添加到内存列表中
record_list.append(record)
#将旧的文件读一行,在新的文件中写一行
with open('ha.conf', 'r') as old, open('new.conf', 'w') as new:
#如果读到backend,判断是否需要写到新的文件中
flag = False
for line in old:
#匹配到backend和输入的内容www.oldboy.org
if line.strip().startswith("backend") and line.strip() == "backend " + backend:
#backend下面的内容不应写到文件中,标记True
flag = True
#接着将backend www.oldboy.org写到新文件中
new.write(line)
#回到内存中将record存放到record_list中的记录写到新的文件中,即"server 100.1.7.9 100.1.7.9 weight 20 maxconn 3000"写到new中
for new_line in record_list:
new.write(" " * 8 + new_line + "\n")
#找到第二个backend,则读一行写一行
if flag and line.strip().startswith("backend"):
#判断需要将backend下面的内容写到文件中,标记False
flag = False
#将当前行写入新的文件中,即backend buy.oldboy.org写到新的文件中
new.write(line)
#加continue,防止下面读一行写一行时重复写backend buy.oldboy.org
continue
#若backend下面的行有数据,则读一行写一行
if not flag and line.strip():
new.write(line) bk = "www.oldboy.org"
rd = "server 100.1.7.59 100.1.7.59 weight 60 maxconn 8000"
add(bk, rd)
最终详尽版(包括查看、增加和删除)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: WangHuafeng import json def check_conf(check_info):
flag = False
check_list = []
with open('ha.conf') as f:
for line in f:
if line.startswith('backend'):
if check_info == line.strip().split()[1]:
flag = True
continue
if flag and line.strip().startswith('backend'):
break
if flag and line.strip():
check_list.append(line.strip())
return check_list def add_conf(backend, record_conf):
print("传入add函数后的值,backend is %s, record is : %s" % (backend, record_conf))
#调用check_conf函数将查询到的server信息添加到列表中
add_list = check_conf(backend)
print("查询原文件中记录存入列表:%s" % add_list)
#如果记录不存在,则将原文件内容写入新文件中,并在新文件末尾添加记录
if not add_list:
with open('ha.conf') as old, open('new_ha.conf', 'w') as new:
for line in old:
new.write(line)
#在末尾直接添加记录,注意换行
new.write("\nbackend " + backend + "\n")
new.write(" "*8 + record_conf)
else:
#如果添加的记录存在
if record_conf in add_list:
print("记录已存在。")
#原文件中有backend+server记录,但输入的记录需要更新到该记录下
else:
#将旧文件写入新文件标志位
flag = False
#写入add_list中存放的记录标志位
write_flag = False
#先输入的server记录存入列表中
add_list.append(record_conf)
#一边读旧文件一边写新的文件
with open("ha.conf") as old, open("new_ha.conf", 'w') as new:
for line in old:
#print("逐行打印文件:%s" % line)
#查找backend行
if line.startswith('backend'):
#print("打印backend开头的信息:%s" % line)
#遇到匹配的记录后,需要将backend所在行的记录写入新文件
if backend == line.strip().split()[1]:
new.write(line)
#打开写文件标志
flag = True
continue
#若再次匹配到backend说明到了下一个以backend开头的行,则反转写文件标志位
if line.startswith("backend"):
flag = False
#将两行backend之间的文件写入新文件中
if flag:
if not write_flag:
#循环add_list列表将记录写入新文件
for line_record in add_list:
new.write(" "*8 + line_record + "\n")
write_flag = True
else:
new.write(line) def delete_conf(backend, record_conf):
# print("backend : %s" % backend)
# print("record : %s" % record_conf)
# 调用check_conf函数将查询到的server信息添加到列表中
del_list = check_conf(backend)
# print(check_list)
# 如果记录不存在,则将原文件内容写入新文件中,并在新文件末尾添加记录
if not del_list:
print("您输入的字段不存在。")
else:
# 如果添加的记录存在
if record_conf in del_list:
del_list.remove(record_conf)
# 将旧文件写入新文件标志位
flag = False
# 写入check_list中存放的记录标志位
write_flag = False
# 一边读旧文件一边写新的文件
with open("ha.conf") as old, open("new_ha.conf", 'w') as new:
for line in old:
# 查找backend行
if line.startswith('backend'):
# 遇到匹配的记录后,需要将backend所在行的记录写入新文件
if backend == line.strip().split()[1]:
new.write(line)
# 打开写文件标志
flag = True
continue
# 若再次匹配到backend说明到了下一个以backend开头的行,则反转写文件标志位
if line.startswith("backend"):
flag = False
# 将两行backend之间的文件写入新文件中
if flag:
if not write_flag:
# 循环check_list列表将记录写入新文件
for line_record in del_list:
new.write(" " * 8 + line_record + "\n")
write_flag = True
else:
new.write(line)
else:
print("您输入的记录不存在。") def menu():
print(
"""
**********操作编号***********
1 查看
2 增加
3 删除
*****************************
"""
) def json_conf(record,input_conf):
print("json is : %s %s" % (record, input_conf))
dict_conf = json.loads(record)
backend = dict_conf['backend'] record_conf = "server %s %s weight %d maxconn %d" % (dict_conf['record']['server1'],
dict_conf['record']['server2'],
dict_conf['record']['weight'],
dict_conf['record']['maxconn']) print("处理完成后,backend is : %s ,record is : %s" % (backend, record_conf))
if input_conf == '2':
add_conf(backend, record_conf)
if input_conf == '3':
delete_conf(backend, record_conf) def main():
menu()
flag = False
while not flag:
input_conf = input("请输入操作编号:")
if input_conf == '1':
check_info = input("请按照以下格式输入:(www.oldboy.org) ")
if check_conf(check_info):
flag = True
for k,v in enumerate(check_conf(check_info),1):
print(k,':',v)
else:
print("您输入的字段不存在。")
flag = False
elif input_conf == '2':
add_info = input('''请按照以下格式添加数据:
{"backend":"www.oldboy.org","record":{"server1":"100.1.27.9","server2":"100.1.37.19","weight":20, "maxconn":3000}}
''')
json_conf(add_info, input_conf)
flag = True
elif input_conf == '3':
del_info = input('''请按照以下格式添加数据:
{"backend":"www.oldboy.org","record":{"server1":"100.1.7.9","server2":"100.1.7.19","weight":20, "maxconn":3000}}
''')
json_conf(del_info, input_conf)
flag = True
else:
print("你输入的操作编号不存在,请重新输入")
flag = False if __name__ == '__main__':
main()
装饰器
s1.py
#在函数的外部进行装饰,在不改变调用函数的基础上,可以在执行函数前或执行函数后添加一个功能
def outer(func):
def inner():
print('log')
return func()
return inner @outer
def f1():
print("F1") @outer
def f2():
print("F2") @outer
def f100():
print("F100")
s2.py
import s1
s1.f1()
s1.f2()s100.f2()
函数整体可以当参数传递
def f1():
print('123') #xxx代指函数f1()整体,函数整体可以当作参数传递
def f2(xxx):
xxx() f2(f1)
装饰器功能
def outer(func):
def inner():
print('log')
ret = func()
print("after")
return ret
return inner # @ + 函数名
# 功能:
# 1、自动执行outer函数并且将其下面的函数名f1当作参数传递
# 2、将outer函数的返回值重新赋值给f1
@outer
def f1():
print("F1")
分析步骤:
def outer(func):
print(123, func) # @ + 函数名
# 功能:
# 1、自动执行outer函数并且将其下面的函数名f1当作参数传递
# 2、将outer函数的返回值重新赋值给f1
@outer
def f1():
print("F1") #执行过程:1.执行outer(),并将函数f1当作参数传递给outer,即outer(f1)
# 2.打印123,并将返回值123赋值给f1,即f1 = 123,所以打印f1时,显示123
s2.py
def outer(func):
#inner函数替代f1函数
def inner():
print("before")
return inner @outer
def f1():
print("F1")
s1.py
import s2 s2.f1()
s2.py
def outer(func):
#f1变成func
#inner函数替代f1函数
def inner():
print("before")
func()
print("after")
return inner @outer
def f1():
print("F1")
s1.py
import s2 s2.f1()
详解装饰器执行过程
装饰器返回值
s2.py
def outer(func):
def inner():
print("before")#如果原函数有返回值需要在装饰器函数中添加返回
r = func()
print("after")#将原函数中的返回值返回
return r
return inner @outer
def f1():
print("F1")
return "haha" @outer
def f2():
print("F2")
s1.py
import s2 # f1被装饰器装饰后返回值为None,如果原函数有返回值需要在装饰器函数中添加返回
ret = s2.f1()
print(ret)
s2.f2()
传递参数
一个参数:
def outer(func):
def inner():
print("before")
#如果原函数有返回值需要在装饰器函数中添加返回
r = func()
print("after")
#将原函数中的返回值返回
return r
return inner @outer
def f1():
print("f1")
return "haha"
import s2 # f1被装饰器装饰后返回值为None,如果原函数有返回值需要在装饰器函数中添加返回
ret = s2.f1("fish")
print(ret)
多个参数
def outer(func):
def inner(*args, **kwargs):
print("before")
#如果原函数有返回值需要在装饰器函数中添加返回
r = func(*args, **kwargs)
print("after")
#将原函数中的返回值返回
return r
return inner @outer
def f1(arg):
print(arg)
return "haha" @outer
def f2(arg1, arg2):
print("F2")
import s2 # f1被装饰器装饰后返回值为None,如果原函数有返回值需要在装饰器函数中添加返回
ret = s2.f1("fish")
print(ret)
s2.f2("haha", "niu")
装饰器做权限认证
LOGIN_USER = {"is login" : False} def outer(func):
def inner(*args, **kwargs):
if LOGIN_USER['is login']:
r = func(*args, **kwargs)
return r
else:
print("请登录") @outer
def manager():
print("欢迎%s登录" % LOGIN_USER['current_user'])