# 文件处理的三个步骤:打开文件 读或者写 关闭文件
# 打开文件涉及了两方面:open功能让操作系统打开了文件,
# 另一方面open功能返回给应用程序一个文件句柄或者是文件对象
# 文件对象占用的是应用程序资源,打开的文件占用的是操作系统的资源
# 文件打开模式分为2大类:读写操作和读写内容模式
# 可读可写模式:+表示
# 遍历文件:for循环
# 1.控制文件指针移动
# ps:只有0模式可以在t下使用,其中1和2模式只能在b模式下使用
# 但是无论是t模式还是b模式下,移动的都是字节个数
# print(f.tell()) # 告诉你当前指针的位置,
# 他永远参照的计数方式是开头
with open('a.txt', mode='rt', encoding='utf-8') as f:
print(f.tell()) # 0
f.seek(9, 0)
f.seek(3, 0)
print(f.tell()) # 3
with open('a.txt', mode='rb', encoding='utf-8') as f:
print(f.tell()) # 0
f.seek(9, 1)
f.seek(3, 1)
print(f.tell()) # 12
with open('a.txt', mode='rb', encoding='utf-8') as f:
print(f.tell()) # 0
f.seek(0, 2)
print(f.tell()) # 18
# tail-f程序 access.log:日志,记录下来用以后看
# 它可以动态的看有没有人往access.log里面添加东西
# 小练习题:模拟记日志的程序
with open('access.log', mode='at', encoding='utf-8') as f:
f.write('2021-06-09 09:16:00 张三 200.103.110.22 ok\n')
# 这样一运行就会在access.log里面出现以上写的内容,运行一次出现一次
# 我们发现这个时候的时间是静止不变的达不到实时监控的目的
# 这个时候可以用模块的知识
# import time
# time.strftime('%Y-%m-%d %H:%M:%S') # 里面的%x是固定格式
# 斜杠可以不加或者换成其他的符号,看个人习惯。
import time
with open('access.log', mode='at', encoding='utf-8') as f:
f.write('%s 张三 200.103.110.22 ok' % time.strftime('%Y-%m-%d %H:%M:%S'))
# tail-f 实时监控程序追加进来内容的变化:(tail-of)运行的原理
# 有一个用户访问就写一条在access.log里面,不定时的用户访问写内容
# 所以access.log也是不定时的在运行。在写东西进access.log里面
# 需要有一个程序只要有新内容就打印出来到tail-f
# 说白了就是把access.log的东西读出来,读到tail里面,
# 而且是永远只读最后一行所以需要上来就把指针移动到末尾。
# (如果不把指针移动到末尾会造成什么后果?会使得tail记录的数据
# 具有重复性,相当于又把前面的全读下来了。)
# 然后tail-f读取access.log的内容。
# 所以tail-f程序此时需要做的是:先open()access.log这个文件
# 此时因为是用r读取的所以指针在文件的开头,而现在我们需要记录的是
# 用户在访问的时候,机器写下来到access.log传输给tail的实时数据
# 所以光标移动到末尾,读取实时行也相当于最后一行内容。
with open('access.log', mode='rb') as f:
f.seek(0, 2) # 指针的移动很关键
# line = f.readline() # 假设access.log还没有人访问,此时的
# tail-f很明显读取不到,也就是说他的返回值line没有,但是我要一直读
# 而且读到了就输出,读不到还是继续去读,循环的读来达到实时检测的目的
# 这个时候就需要用到循环读取。
while True:
line = f.readline()
if len(line) == 0:
continue
else:
print(line.encode('utf-8'), end='') # 每次读取的返回值
# 因为b模式下读取的是byetes类型,所以需要在进行相应的转换,也就是解码。
# 2.文件修改的两种方式
# 假如test.txt里面内容为(哈哈哈hello黑暗时代)
with open('test.txt', mode='r+t', encoding='utf-8') as f:
f.seek(9, 0)
f.write('hello') # 我们发现乱码了
# hello五个字节,而egon只有4个字节
# 首先我们应该要了解文件只能被覆盖不能被插入
# 5个字节覆盖4个字节多的一个字节就会覆盖下面的
# ‘黑’字,而黑是三个字节所以会出现乱码。
# 我们经常在电脑上操作的复制黏贴并不是我们所觉得的。
# 比如说把你好吗,修改成你好或者在你好的中间插入一些汉字
# ,却没有乱码。这是因为所以的文件修改的行为
# 其实都是模拟出来的,你是你看着像插入,其实他是文件的覆盖
# 更深层次的是新的覆盖旧的。但是内存可以修改
# 把硬盘的数据读到内存,再把内存改完的东西覆盖到硬盘
# 这是事实上所有的文本编辑器的大概原理。
# 文件修改的俩种方式都是把硬盘数据读到内存里面。
# 在内存改完了之后再覆盖到硬盘
# 具体又分为2种方式
# 第一种:
with open('test.txt', mode='rt', encoding='utf-8') as f:
date = f.read() # 赋值给一个变量date,字符串类型
date.replace('egon', 'EGON') # 字符串的替换
with open('test.txt', mode='wt', encoding='utf-8') as f:
f.write(date.replace('egon', 'EGON'))
# 首先分析:如果f.read()也就是原文件过大的话,会造成电脑很卡
# 其次就是千万不要用以下方法进行文件修改
with open('test.txt', mode='rt', encoding='utf-8') as f, \
open('test.txt', mode='wt', encoding='utf-8') as f:
# 这样会造成直接清空,永远也覆盖不了。
# 第二种:
import os
with open('test.txt', mode='rt', encoding='utf-8') as f1, \
open('b.txt.swp', mode='wt', encoding='utf-8') as f2:
for line in f1:
f2.write(line.replace('EGON', 'egon'))
# 这个时候我们需要做的是把原文件删掉,然后新文件改名成原文件的名字,
# 然后需要导入一个模块import os
os.remove('test.txt')
os.rename('b.txt.swp', 'test.txt')
# 总结:以上俩种情况,第二种不费内存,但是虽然不费硬盘,却需要硬盘
# 有一个最小值。假设原文件有10个G,如果第一种的话只需要10个G就行,
# 但是第二种却需要至少20个G才能进行文件的修改。
# 如果自己python写文件的话应该用第二种。
# 一般的文本编辑器都是用第一种,一次性把内容读到
# 内存,修改都是在内存里面修改。
# 3.函数
# 1.什么是函数?
# 函数就是盛放功能(一系列代码)的容器
# 定义函数就是造出来一个工具
# 事先准备工具的过程》函数的定义
# 遇到应用场景拿来就用》函数的调用
# 2.为何要用函数?
# 不用函数写出的代码问题是:
# 2.1程序的组织结构不清晰,可读性差,可维护性差
# 2.2程序的可扩展性差
# 3.如何用函数?
# 原则:先定义后调用
#
# 定义函数的语法
# def 函数名(参数1, 参数2, 参数3,.....):
# '''文档注释''' # 推荐写
# 代码1
# 代码2
# 代码3
# return 值
# 调用函数的语法:
# 函数名(值1,值2,值3)
# res = 函数名 # 拿到返回值
# print('*'*50)
# print('hello'.center(50,''))
# print('='*50)
# 如果想继续得到上面的print输出的值
# 我们可以利用函数的性质来完成
# def func():
# print('*' * 50)
# print('hello'.center(50, ' '))
# print('=' * 50)
# func()
# print(id(func()))
# print(func) # 得到的是函数的内存地址
# f = func # f为函数的内存地址
# f() # 函数的内存地址可以加括号调用
# x() # 变量的却不可以加括号
# print(x) # 得到的是变量值,理论上也是得到内存地址
# 这是因为变量名都做了处理
# x = 10
# 定义变量时,申请内存空间把10丢进去,然后把10的内存地址给X
# 定义函数时,申请内存空间把函数体代码放进去,然后将内存空间地址
# 给函数名
# func() = 函数体代码等
# 2.函数定义阶段发生的事情:只检测语法不执行代码
# 申请内存空间,把函数体代码放进去,然后把内存地址绑定给函数名
# 例1
# def func():
# print(1)
# print( # 语法错误
# print(2)
# 上面这种会直接报错,语法错误
# 例2
# def func():
# print(1)
# absfasf # 不会报错,因为没有语法错误
# 他没有先定义就引用了逻辑错误,应该先定义后引用。
# print(2)
# 上面这种不会报错,判断语法是否错误。
# 例3
# def foo():
# print('from foo')
# bar() # 也不会报错
# 例4
# def foo():
# print('from foo')
# bar()
# def bar():
# print('from foo')
#
# func()
# 函数调用阶段发生的事情:执行代码
# 例4
# def foo():
# print('from foo')
# bar()
# def bar():
# print('from foo')
# func() # 不会报错
# 函数的参数:
# def func(x, y):
# print(x + y)
# func(10, 20) # 30
# 如:
# x = 10
# y = 20
# if x > y:
# print(x)
# else:
# print(y)
# 假如在python写程序的时候经常用到下列代码
# 可以直接写成函数的形式,这样更加方便。
# def func(x, y):
# if x > y:
# print(x)
# else:
# print(y)
# func(20, 10) # 20
# inp_user = input('your name').strip()
# inp_pwd = input('your password').strip()
# if inp_user == 'egon' and inp_pwd == '123':
# print('ok')
# else:
# print('error')
# 这个可以把他弄成函数的形式:
def login(inp_user, inp_pwd):
inp_user = input('your name').strip()
inp_pwd = input('your password').strip()
if inp_user == 'egon' and inp_pwd == '123':
print('ok')
else:
print('error')
# 函数的返回值
l = [11, 22, 33, 44, 55]
def max():
size = len(l)
if size > 3:
print('ok')
else:
print('cuowu')
def max2(sal1, sal2):
if sal1 > sal2:
print(sal1)
else:
print(sal2)
max2(2000, 4000)
# 函数内可以有多个return,但只要执行一次,整个函数就立即结束
# 并且将return后的值作为本次调用的产品返回。
# def func():
print(1)
return 111111
print(2)
return 22222
func() # 1
res = func() # 111111
# 具体来说函数的返回值有三种形式
# 1.return 值:返回的就是该值本身
# 2.return 值1 值2 值3:返回的是小元组(值1, 值2, 值3)
def func():
return 111, 222, ['sss']
res = x, y, z = func()
print(x, y, z)
# print(res) # 返回值返回的是小元组
# 3.没有return:默认的返回值是None
def func():
pass
res = func()
print(res)
登录注册转提现都可以写
# 4.模块
# 1.什么是模块
# 模块是一系列功能的集合体
# 模块分为四种通用的类别
# 使用python编写的.py文件
# 模块有三种来源
# 1python自带的模块/库
# 内置模块(python解释器自带的)
# 标准库(python官方觉得不错的)
# 2第三方库
# 3.自定义库
# 2.为何要用模块
# 1拿来主义,提升开发效率
# 2减少代码的冗余
# 3.如何用模块
# import
# from...import
# 必须要加上模块名.加前缀
import spam # 模块名
print(spam.x) # 100
spam.f1() # from f1
spam.f2() # from f2
import time # 模块名
from spam import x, f1, f2 # from 模块名 import ...
f1() # from f1
print(f1) # <function f1 at 0x000002A7A50DA790>
print(f1()) # from f1 和 2222
res = f1()
# 常用模块的使用
# time模块 跟时间有关系
import time
# 时间戳
print((time.time())) # 距离1970年到今天的秒数
# 这个可以做时间的运算
# 格式化的字符
print(time.strftime('%Y-%m-%d %H:%M:%S'))
# 结构化的时间
obj = time.localtime() # 显示的是东八区的时间线
print(obj)
time.struct_time(tm_year=2021, tm_mon=6, tm_mday=10, ......)
print(obj.tm_yea) # 2021
# 可以获取时间的某一部分
obj2 = time.gmtime() # 显示的是国际时间
# 4.1模块的使用
# import
# from....import
# 5.常用模块
# random模块
import random # 模块名
# print(random.random()) # 取随机值 0到1之间的随机小数
# print(random.randint(1, 3)) # 取随机值 1到3的随机整数
# print(random.randrange(1, 3)) # 取随机值 1-2的随机整数
# print(random.choice([11, 'aa', 3])) # 取随机值 从列表里面随机取1个
# print(random.sample([1, 3], 2)) # 取随机值 从列表里面随机取2个
# print(random.uniform(1, 3)) 取随机值 大于1跟小于3的小数
# item = [1, 2, 3, 4, 5, 6]
# random.shuffle(item)
# print(item) # 随机打乱item列表的顺序
# 储备知识,写随机验证码
# print(chr(65)) # 里面的数字按照ASCII码一一对应相应的大写英文字母
# print(chr(90))
# print(ord('A')) # 里面的英文字母按照ASCII码对应相应的数字
# print(ord('Z'))
# 第一种:
# j = str(random.randint(0, 9)) # 把数字变成字符串,方便后面拼接
# item = chr(random.randint(65, 90))
# res= random.choice([i, j])
#
# j = str(random.randint(0, 9)) # 把数字变成字符串,方便后面拼接
# item = chr(random.randint(65, 90))
# res1= random.choice([i, j])
#
# j = str(random.randint(0, 9)) # 把数字变成字符串,方便后面拼接
# item = chr(random.randint(65, 90))
# res2= random.choice([i, j])
# j = str(random.randint(0, 9)) # 把数字变成字符串,方便后面拼接
# item = chr(random.randint(65, 90))
# res3= random.choice([i, j])
# print(res + res1 + res2 + res3)
# 第二种方案:
# res = ''
# for i in range(4): # 这个用的很巧妙
# j = str(random.randint(0, 9)) # 把数字变成字符串,方便后面拼接
# item = chr(random.randint(65, 90))
# res += random.choice([item, j])
# print(res)
# 这个for循环用的很巧妙,只利用他for循环的次数,不在乎他取的值。
# 第三种方案:
# def make_code():
# res = ''
# for i in range(4):
# j = str(random.randint(0, 9))
# item = chr(random.randint(65, 90))
# res += random.choice([item, j])
# return res
# print(make_code())
# os模块 # 跟操作系统有关系,主要是掉文件相关的功能
import os
# print(os.getcwd()) #获取你当前所在的文件夹
# os.getcwd() # 获取当前工作目录,即当前python脚本工作的目录路径
# os.chdir("dirname") # 改变当前脚本工作目录;相当于shell下cd
# os.curdir # 返回当前目录: ('.')
# os.pardir # 获取当前目录的父目录字符串名:('..')
# os.makedirs('dirname1/dirname2') # 可生成多层递归目录
# os.removedirs('dirname1') # 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
# os.mkdir('dirname') # 生成单级目录;相当于shell中mkdir dirname
# os.rmdir('dirname') # 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
# os.listdir('dirname') # 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
# os.remove() # 删除一个文件
# os.rename("oldname","newname") # 重命名文件/目录
# os.stat('path/filename') # 获取文件/目录信息
# os.sep # 输出操作系统特定的路径分隔符,win下为"\"但是前面要加r如rD:\..., Linux下为"/"
# os.linesep # 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
# os.pathsep # 输出用于分割文件路径的字符串 win下为;,Linux下为:
# os.name # 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
# os.system("bash command") # 运行shell命令,直接显示
# os.environ # 获取系统环境变量
# 环境变量,里面是字典的形式。在所有文件都可以应用
# 可以把经常用到的变量丢到环境变量里面需要的时候可以随时用
# os.environ['username'] = 'egon'
# os.path.abspath(path) # 返回path规范化的绝对路径
# os.path.split(path) # 将path分割成目录和文件名二元组返回
# os.path.dirname(path) # 返回path的目录。其实就是os.path.split(path)的第一个元素
# os.path.basename(path) # 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
# os.path.exists(path) # 如果path存在,返回True;如果path不存在,返回False
# os.path.isabs(path) 如果path是绝对路径,返回True
# os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
# os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False
# os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
# os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间
# os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
# os.path.getsize(path) 返回path的大小
os.system() # 运行系统命令
# 在系统终端CMD使用下
tasklist # 可以看系统正在进行的所有进程
tasklist | findstr chrome
# import os
# print(os.system('tasklist'))
# 如果想从系统中筛选某一系统进程的话
# tasklist | findstr 某一系统进程
# tasklist命令如果想传给下一条命令
# 需要加 | 前一条命令是把结果丢到管道里面
import time
import os
# os.system('tasklist')
# print(os.getpid()) # pid程序的身份证号
# # taskkill /F /PID 15223 # 结束某个进程
# time.sleep(1000) # time模块的功能
print(os.system('taskkill /F /PID 7116')) # 杀死某个进程,通过id
import subprocess # 模块名
os.system('tasklist') # 跟以下类似,但是os会形成乱码
obj = subprocess.Popen('tasklist', shell=True,stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
res1 = obj.stdout.read()
res2 = obj.stderr.read()
print(res1.decode('gbk'))
进程和进程之间互不干扰,但是每个进程一般都有子进程,
子进程的运行间接受父进程影响,父进程在子进程没运行
完毕程序就结束终端了,子进程就运行不了。