1、把文件的全部内容都读到内存中,然后把原有的文件内容清空,重新写新的内容
with open('a.txt','a+') as f:
f.seek(0)
res=eval(f.read())
res['jmy']=123456
f.seek(0)
f.truncate()#清空文件
f.write(str(res))#write方法并不直接将数据写入文件,而是先写入内存中特定的缓冲区
f.flush()#刷新缓冲区,即将缓冲区中的数据立刻写入文件,同时清空缓冲区
2、把修改后的文件内容写到一个新的文件中,删除原来的文件,再把新文件重命名为原来的文件-这种方式效率更高
import os
with open('a.txt',encoding='utf8') as a,open('b.txt','w',encoding='utf8') as b: # 这个是多文件的操作,打开两个文件,fr是读file.txt,fw是新建一个file_bak文件
for line in a: # a.txt中的每一行
new_line = line.replace('集合', '**')
b.write(new_line) # 写到file_bak文件中
os.remove('a.txt')
os.rename('b.txt','a.txt')
3、函数
#函数、方法
#函数就是实现一个功能的一代码
#为了帮你节省代码的
#函数必须调用才会执行
#函数名不可以重复
#定义函数时写的入参叫做形参,调用函数的时候传的参数叫做实参
def sayName(name,age,sex):#有入参,形参,位置参数
print('say %s'%name)
print('say %s'%age)
print('say %s'%sex)
---函数体---
sayName('nina')#调用时传的实参
sayName('nina',18,'女')#调用时传的实参
#函数如果要有返回值的话,就写return,函数里面遇到return时函数立即结束
#函数不是必须有返回值的,如果不写return,默认返回None
#函数里面不return,你是获取不到运算结果的
def calc(a,b):
return a*b
res=calc(2,3)
print(res)
#函数即变量,如:
a=isfloat
print(a('-43'))
例如:写一个函数:能判断输入的字符串是不是小数类型的
#1、判断小数点的个数是否是1:count()
#2、判断小数点的右边是否为整数:isdigit()
#3、判断小数点左边 1)是否为整数:isdigit(),2)负整数按照负号分割split('-’)取负号右边的如果是整数:
def isfloat(s):
s=str(s)
if s.count('.')==1:
left_str=s.split('.')[0]
right_str=s.split('.')[-1]
if right_str.isdigit():
if left_str.isdigit():
return True
elif left_str.count('-') and left_str.startswith('-'):
tmp_num=left_str.split('-')[-1]
if tmp_num.isdigit():
return True
return False
a=isfloat('-43')
print(a)
#函数例子
def welcome():
print('欢迎光临')
def exit_sys():
exit('退出程序')
def buy():
print('选择你要买什么:')
choice=input('请输入你的选择:1欢迎 2退出 3买东西')
menu={'1':welcome,
'2':exit_sys,
'3':buy
}
menu[choice]()
4、函数参数
#name是必填参数,位置参数
#sex='male'是默认值参数,不是必填的
#*args是可变参数,不是必填的
#**kwargs是关键字参数,不是必填的
#如果这四种参数要连起来使用时,必须按照必填参数、默认值参数、可变参数、关键字参数的顺序来写
#在调用函数的时候,位置传参这种方式是要写在关键字传参前面的
def sayhello(name,sex='male',*args,**kwargs):
print('名字是%s,性别是%s'%(name,sex))
print('**kwargs的值是',kwargs)
print('*args的值是',args)
name=input('请输入名字:')
sex=input('请输入性别:')
sayhello(name,sex)
sayhello(name,sex,1867776663,'nihao')
sayhello(name,sex,187767423432,'nihao',age=18,love='cat')
sayhello('nina',sex='male','hello')#这样是错误的,位置传参在关键字传参后面了
#可变参数和关键字参数在参数比较多或者参数不确定时多少个的情况下,可以使用
def run_case(case_id,case_name,project,detail,req_url,req_param,method,check,tester):#---有太多参数的不方便
def run_case(*args):#---使用可变参数较为方便
如使用方法1:for i in args:
如使用方法2:case_name=args[1]
5、局部变量和全局变量
局部变量是在函数内部定义的变量,在函数内可以随便使用,一旦出了函数,name就不能使用了
全局变量是大家都可以使用的变量
全局变量是字典或者list的话,不需要用global声明就可以直接修改,其他类型(str,元组,集合。。。)如果要修改值,必须用global声明
能不用全局变量的时候尽量不用全局变量
例如:
ljt=['垃圾桶:']
def nina():
money=200
ljt=[]
ljt.append('扔了100')
print(money-100)
print(ljt)
def wxc():
money=10000
ljt.append('扔了2000')
print(money-2000)
d={'redbag':9999}
def wxc():
d['money']=100
def nina():
d['money']=2000
6、递归:函数自己调用自己
递归调用的特性:
1\必须有一个明确的结束条件
2\每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3\递归效率不高,递归层次过多会导致栈溢出
def a(count=0):
print('hahaha')
a()
def wxc():
num = int(input('请输入一个数字:'))
if num%2 == 0:
print('是整数')
return
else:
print('是奇数')
wxc()
wxc()
7、集合
list=[1,2,2,2,1,1,3,4,5,5,6]
set(list)#去重:{1, 2, 3, 4, 5, 6}
slist=set(list)
s={1,2,3,4,5}
s=set()#定义一个空集合
非空即真,非零即真
talk=input('say:').strip()
if 0:#if talk:
print('true')
else:
print('false')
例如:
xn=['alsa','lily','jack']
python=['nina','alsa','jack','mum']
s_xn=set(xn)
s_python=set(python)
print(s_xn.intersection(s_python)) # 取交集
print(s_xn & s_python) # 取交集
print(s_xn.union(s_python)) # 取并集
print(s_xn | s_python) # 取并集
print(s_xn.difference(s_python)) # 取差集 在s_xn中存在,在s_python中没有的
print(s_xn - s_python)
list1 = {1, 2, 3, 4, 5, 6, 9}
list2 = {2, 3, 4, 6, 1}
list3 = {1, 2, 3}
print(list3.issubset(list1)) # 判断list3是不是list1的子集
print(list1.issuperset(list3)) # 判断list1是不是list3的父集
print(list1.isdisjoint(list3)) # 判断list1和list3是否有没有交集,没有交集时返回True
print(list1.symmetric_difference(list2)) # 对称差集,输出两个列表中都没有的值,也就是把两个集合中相同的去掉
print(list1 ^ list2)# 对称差集
list1.add(888) # 添加元素
list1.update([777, 666, 666])
print(list1)
list1.remove(777) # 删除元素,如果元素不存在会报错
list1.discard(9) # 如果删除的元素存在,删除,不存在不做处理
print(list1)
list1.pop() # 删除一个随机的元素,并返回删除的元素
print(list1)
8、小程序:用交集的方式产生密码:
import random,string
num = input('请输入一个数字:').strip()
pwds=set()
if num.isdigit():
while len(pwds)<int(num):
passwd=set(random.sample(string.ascii_letters+string.digits,8))
set1=set(string.ascii_uppercase).intersection(passwd)
set2=set(string.ascii_lowercase).intersection(passwd)
set3=set(string.digits).intersection(passwd)
if set1 and set2 and set3:
str_passwd = ''.join(passwd)+'\n'
pwds.add(str_passwd)
with open('pwds.txt','w') as fw:
fw.writelines(pwds)
else:
print('你输入的不是数字!')
9、小程序:监控日志的脚本:
#一分钟内访问次数超过200次的,就给这个ip加入黑名单
#1、一分钟读一次日志
#2、获取一分钟内所有访问的ip
#3、判断ip出现次数,超过200,加入黑名单
#4、每次读文件都是从文件开头开始读的,导致重复读取以前读过的,要记录每次读完后的文件指针,再用seek移动到哪个位置 tell()
# line='178.210.90.90 - - [04/Jun/2017:03:44:13 +0800] "GET /wp-includes/logo_img.php HTTP/1.0" 302 161 "http://nnzhp.cn/wp-includes/logo_img.php" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.99 Safari/533.4" "10.3.152.221"'
# print(line.split()[0])#取ip
import time
pin=0#默认文件指针是0
while True:
with open('access.log') as fr:
ips = []
fr.seek(pin)#移动指针
for line in fr:
ip = line.split()[0] # 取ip地址
ips.append(ip)
# 要判断每个ip出现的次数是否超过200次
for ip in set(ips):
if ips.count(ip) > 200:
print('要把这个ip加入黑名单:%s' % ip)
pin=fr.tell()#记录已经读到的文件位置
time.sleep(60)