主要学习内容:修改文件、集合、函数、模块
修改文件两种方法
修改文件方法一(缺点:代码繁琐,一次性将文件读出,文件过大可能会卡住)
1 with open('geci', 'a+', encoding='utf-8') as f: 2 f.seek(0) # 指针移到最前面 3 all = f.read() # 读取文件内容 4 new_all = all.replace('一', '二') # 将文件中的‘一’替换为‘二’ 5 f.seek(0) # 指针移到最前面 6 f.truncate() # 清空文件内容 7 f.write(new_all) # 写入处理后的内容 8 f.flush() # 立即刷新
修改文件方法二(代码简单,推荐)
1 import os 2 with open('geci', 'a+', encoding='utf-8') as f1, open('geci.bak', 'w', encoding='utf-8') as f2: 3 f1.seek(0) 4 for line in f1: 5 new_line = line.replace('一', '二') # 将字符串的a替换为b 6 f2.write(new_line) 7 8 os.remove('geci') # 删除geci文件 9 os.rename('geci.bak', 'geci') # 将geci.bak重命名为geci 10 os.remove('geci.bak') # 删除geci.bak文件
练习1:
ngix日志,写一个监控位置日志脚本,如果统一IP地址在60s访问超过20次,那么就把ip列入黑名单
需求分析:
1、60秒读一次文件
2、分割,取到第一个元素,ip地址
3、把所有的ip加入到一个list里,如果ip次数超过20次,加入黑名单
1 import time 2 point = 0 3 while True: 4 ips = [] # 存放所有的ip地址 5 with open('access.log', encoding='utf-8') as f: 6 for line in f: 7 ip = line.split()[0] 8 ips.append(ip) 9 if ips.count(ip)>19: 10 print('已经把%s加入黑名单'%ip) 11 point = f.tell() 12 time.sleep(60)
集合(set)
1 s = set() # 定义空的集合 2 s2= {'1', '2', '3'} # 定义集合 3 # 集合是无序的,所以没有办法通过下标取值 4 s2.add('5') # 添加值 5 s2.remove('1') # 删除指定元素 6 s2.pop() # 删除 7 s3 = {'2', '3', '5'} 8 print(s2.intersection(s3)) # 取交集 9 print(s2 & s3) # 取交集 10 print(s3.union(s2)) # 取并集 11 print(s2 | s3) # 取并集 12 print(s3.difference(s2)) # 取差集,s3里 s2里没有的元素 13 print(s3 - s2) # 取差集
函数
将一堆代码封装起来,提高代码的复用性
定义函数:
def 函数名():
函数体
调用函数:函数只有调用时,才会被执行
形参:形式参数,定义函数时的参数,即变量
位置参数(或必填参数):不填就会报错
默认值参数:非必填,不传的话 就按默认值
非固定参数:分为可变参数、关键字参数
可变参数(非必传,存放为元组):
用*来接收,后面想传多少个参数就传多少个,如果位置参数、默认值参数、可变参数一起使用的的话,可变参数必须在位置参数和默认值参数后面。
1 def test(a, b=1, *args): 2 print('a', a) 3 print('b', b) 4 print('args', args) 5 6 test('haha', '2', '3', '4', '5')
关键字参数(非必传,存放为字典):
用**来接收,后面的参数也是不固定的,想写多少个写多少个,当然也可以和上面的几种一起来使用,如果要一起使用的话,关键字参数必须在最后面。
使用关键字参数的话,调用的时候必须使用关键字传参。
1 def test2(**kwargs): 2 print(kwargs) 3 4 test2(name='da', age='18')
实参:实际参数,调用函数时的参数,即调用函数时传入的值
参数调用方法:位置调用和关键字调用
1 def test(a, b=1, *args): 2 print('a', a) 3 print('b', b) 4 print('args', args) 5 6 test('haha', '3', '4', '5') # 位置调用 7 t = [1,2,3,4,5] 8 test(*t) # 关键字调用
return用法:
1、获取返回值:如果想获取函数的结果,必须return;如果函数没写return的话,返回值是None;
return不是必须写的,需要获取函数的返回结果才用写
2、函数遇到return立即结束,相当于循环里的break
全局变量和局部变量
局部变量:函数里面定义的变量
全局变量:在函数外面定义的变量
global 变量名:想在函数里面修改函数外的变量,需要先声明全局变量
练习2
写一个校验字符串是否为合法的小数
0.88
-0.99
1、小数点的个数是否为1
2、按小数点分隔,判断 元素是否为整数
3、第一个元素为负号,则为负数
1 def check_float(s): 2 s = str(s) 3 if s.count('.') == 1: 4 s_list = s.split('.') 5 left = s_list[0] 6 right = s_list[1] 7 if left.isdigit() and right.isdigit(): 8 return True 9 elif left.startswith('-') and left.count() == 1: 10 if left.split('-')[-1].isdigit() and right.isdigit(): 11 return True 12 return False 13 14 print(check_float('-ss.05'))
递归
递归调用,就是自己调用自己;递归函数,就是在函数在内部调用自身本身;
用递归实现的,用循环都能实现,最好别用递归,效率不高
递归最多能递归999次
模块
分为标准模块、第三方模块、自己写的模块
标准模块:python自带的,不需要安装的
第三方模块:别人提供的,需要安装
自动安装命令 pip install 模块名
手动安装:直接搜要安装的模块,下载下来(tar.gz格式),在解压文件中找到setup.py,在电脑路径栏输入cmd(或者 在setup.py路径下,shift+右键 在此打开cmd窗口),然后在打开的cmd窗口中输入命令python setup.py install,安装完后安装包就可以删掉了
自己写的模块:自己写的python文件
import xx 导入文件,导入一个文件的实质是把这个python文件从头到尾运行一次
import在导入文件的时候,首先从当前目录下找这个文件,然后从python的环境变量里面找。
如何查看python的环境变量呢?
import sys
print(sys.path()) # python 的环境变量
环境变量就是让一个命令,不管在哪个目录下都可以执行