十七、函数里的模块
十七、函数里的模块
1. 模块的定义
模块就是一个.py结尾的python代码文件(文件名为hello.py,则模块名为hello), 用于实现一个或多个功能(变量,函数,类等)
2. 模块的分类
- 标准库(python自带的模块,可以直接调用)
- 开源模块(第三方模块,需要先pip安装,再调用)
- 自定义模块(自己定义的模块)
3. 模块的存放路径
模块主要存放在/usr/local/lib/python3.6/目录下,还有其它目录下。使用sys.path查看。
# python3.6
>>> import sys
>>> print(sys.path) # 模块路径列表,第一个值为空代码当前目录
['', '/usr/local/lib/python36.zip', '/usr/local/lib/python3.6',
'/usr/local/lib/python3.6/lib-dynload', '/root/.local/lib/python3.6/site-packages',
'/usr/local/lib/python3.6/site-packages']
# sys.path和linux上的$PATH很类似,如果两个目录里分别有同名模块,则按顺序来调用目录靠前的。
# sys.path的结果是一个列表,所以你可以使用sys.path.append()或sys.path.insert()增加新的模块目录。
4. 模块的基本导入语法
import导入方法相当于是直接解释模块文件
import导入单模块
import hello
import导入多模块
import module1,module2,module3
from导入模块里所有的变量函数
from hello import *
from导入模块文件里的部分函数
from hello import functi1,funct2
import语法导入与from语法导入的区别
区别1:import导入模块里的所有函数,而from可以选择只导入模块里部分的函数(为了优化,只导入自己要用的)
区别2:调用import导入模块需要前面接模块名,而from语法不用
import hello
hello.test1() # 前面要接模块名
from hello import *
test1() # 前面不用接模块名
前面不加模块名会产生一个问题,如果当前代码文件里的函数名与调用模块的函数名冲突怎么办呢?
为了区分本地funct1和导入的hello模块里的funct1,可以导入时做别名
from hello import funct1 as hello_funct1
示例:利用别名来解决模块与本地函数冲突的问题
from hello import funct1 as hello_funct1
def funct1():
print("local funct1")
hello_funct1() # 用别名来调用hello模块里的funct1
funct1() # 本地的funct1
5. 标准库之os模块(重点)
import os
print(os.getcwd()) # 查看当前目录
os.chdir("/tmp") # 改变当前目录
print(os.curdir) # 打印当前目录.
print(os.pardir) # 打印上级目录..
os.chdir(os.pardir) # 切换到上级目录
print(os.listdir("/")) # 列出目录里的文件,结果是相对路径,并且为list类型
print(os.stat("/etc/fstab")) # 得到文件的状态信息,结果为一个tuple类型
print(os.stat("/etc/fstab")[6]) # 得到状态信息(tuple)的第7个元素,也就是得到大小
print(os.stat("/etc/fstab")[-4]) # 得到状态信息(tuple)的倒数第4个元素,也就是得到大小
print(os.stat("/etc/fstab").st_size) # 用这个方法也可以得到文件的大小
print(os.path.getsize(__file__)) # 得到文件的大小,__file__是特殊变量,代表程序文件自己
print(os.path.getsize("/etc/fstab")) # 也可以指定想得到大小的任意文件
print(os.path.abspath(__file__)) # 得到文件的绝对路径
print(os.path.dirname("/etc/fstab")) # 得到文件的绝对路径的目录名,不包括文件
print(os.path.basename("/etc/fstab")) # 得到文件的文件名,不包括目录
print(os.path.split("/etc/fstab")) # 把dirname和basename分开,结果为tuple类型
print(os.path.join("/etc","fstab")) # 把dirname和basename合并
print(os.path.isfile("/tmp/1.txt")) # 判断是否为文件,结果为bool类型
print(os.path.isabs("1.txt")) # 判断是否为绝对路径,结果为bool类型
print(os.path.exists("/tmp/11.txt")) # 判断是否存在,结果为bool类型
print(os.path.isdir("/tmp/")) # 判断是否为目录,结果为bool类型
print(os.path.islink("/etc/rc.local")) # 判断是否为链接文件,结果为bool类型
os.rename("/tmp/1.txt","/tmp/11.txt") # 改名
os.remove("/tmp/11.txt") # 删除
os.mkdir("/tmp/aaa") # 创建目录
os.rmdir("/tmp/aaa") # 删除目录
os.makedirs("/tmp/a/b/c/d") # 连续创建多级目录
os.removedirs("/tmp/a/b/c/d") # 从内到外一级一级的删除空目录,目录非空则不删除
os.popen()和os.system()可以直接调用linux里的命令,二者有一点小区别:
# 下面这两句执行操作都可以成功
os.popen("touch /tmp/222")
os.system("touch /tmp/333")
print(os.popen("cat /etc/fstab").read()) # 通过read得到命令的内容,可直接打印出内容,也可以
赋值给变量
print(os.system("cat /etc/fstab")) # 除了执行命令外,还会显示返回值(0,非0,类似shell里$?判断用
的返回值)
# 所以如果是为了得到命令的结果,并想对结果赋值进行后续操作的话,就使用os.popen(cmd).read()
6. 标准库之re模块(扩展)
正则表达式简介
re是regex的缩写,也就是正则表达式
# grep ^daemon /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
# awk '/^daemon/{print $0}' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
# sed -n '/^daemon/p' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
表达式或符号 | 描述 |
---|---|
^ | 开头 |
$ | 结尾 |
[abc] | 代表一个字符(a,b,c任取其一) |
[^abc] | 代表一个字符(但不能为a,b,c其一) |
[0-9] | 代表一个字符(0-9任取其一) |
[a-z] | 代表一个字符(a-z任取其一) |
[A-Z] | 代表一个字符(A-Z任取其一) |
. | 一个任意字符 |
* | 0个或多个前字符 |
.* | 代表任意字 |
+ | 1个或多个前字符 |
? | 代表0个或1个前字符 |
\d | 匹配数字0-9 |
\D | 匹配非数字 |
\w | 匹配[A-Za-z0-9] |
\W | 匹配非[A-Za-z0-9] |
\s | 匹配空格,制表符 |
\S | 匹配非空格,非制表符 |
{n} |
匹配n次前字符 |
{n,m} |
匹配n到m次前字符 |
示例:验证是强密码还是弱密码
import re
passwd = input("请输入你的密码:")
def passwd_check(passwd):
if len(passwd) < 8:
print("密码长度不够")
exit()
else:
# if (re.findall("[a-z]",passwd)) and (re.findall("[A-Z]", passwd)) and (re.findall("\d",passwd)) and (re.findall("_",passwd)):
if (re.findall("\w",passwd)) and (re.findall("_",passwd)):
print("密码是强密码")
else:
print("密码是弱密码")
passwd_check(passwd)
re模块常用操作
模块+函数(方法) | 描述 |
---|---|
re.match() | 开头匹配,类似shell里的^符号 |
re.search() | 整行匹配,但只匹配第一个 |
re.findall() | 全匹配并把所有匹配的字符串做成列表 |
re.split() | 以匹配的字符串做分隔符,并将分隔的转为list类型 |
re.sub() | 匹配并替换 |
示例: re.match
import re
print(re.match("^root","herl:x:2:2:root:/root:/sbin/nologin")) # 结果为none,表示匹配未成功
print(re.match("^root","root:x:2:2:root:/root:/sbin/nologin")) # 有结果输出,表示匹配成功
abc=re.match("aaa\d+","aaa234324bbbbccc")
print(abc.group()) # 结果为aaa234324,表示打印出匹配那部分字符串
示例: re.search
import re
print(re.search("aaa","sdfaaasdaaawwsdf")) # 有结果输出,表示匹配成功;re.search就是全匹配,而不是开头(但只返回一个匹配的结果);想开头匹配的话可以使用^aaa
b=re.search("^root","root:x:2:2:root:/root:/sbin/nologin")
print(b.group()) # 验证,确实只返回一个匹配的结果,并使用group方法将其匹配结果打印出来
示例: re.findall
import re
print(re.findall("aaa\d+","aaa111222bbbbcccaaaa333444")) # 没有group()方法了,结果为
['aaa111222', 'aaa333444']
print(re.findall("aaa\d+|ddd[0-9]+","aaa111222bbbbddd333444")) # 结果为['aaa111222',
'ddd333444']
小结:re.search()与re.findall()
都不是开头匹配
re.search()只匹配一行里第一个,而re.findall()会把一行内匹配的多个都匹配出来
re.search()可以通过group()打印匹配的结果,re.findall()没有group()方法,直接匹配的所有结果以列表的形式展示
示例: re.split
import re
print(re.split(":","root:x:0:0:root:/root:/bin/bash")) # 以:分隔后面字符串,并转为列表
示例: re.sub
import re
print(re.sub(":","-","root:x:0:0:root:/root:/bin/bash")) # 全替换:成-
print(re.sub(":","-","root:x:0:0:root:/root:/bin/bash",count=3)) # 只替换3
运维文本的处理操作一般只有三种:
1. 行匹配
· 按行号来
· 按正则匹配
2. 截取
打印文件里最后一列
import re
f = open("f://1.txt")
for i in f:
# abc = re.split(":",i)
# print(abc[len(abc)-1].strip()) # len()算长度,通过长度-1得到最后一列的下标
# print(i.strip().split(":")[-1]) # 用字符串的split方法切分,再通过下标-1得到结果
print(re.split(":", i.strip())[-1])
f.close()
统计文件里的root关键字一共出现了几次(split的写法)
import re
f = open("f://1.txt")
sum = 0
for i in f:
if re.findall("root", i):
line_list1 =re.split("root", i)
sum += len(line_list1) -1
print(sum)
f.close()
3. 统计
打印文件里以root开头的行
f= open("f://1.txt")
for i in f:
#if i.startswith("root"):
if re.match("root",i):
#if re.findall("^root",i):
#if re.search("^root",i):
print(i)
f.close()
统计文件里有root的行
f= open("f://1.txt")
for i in f:
if re.search("root",i):
print(i)
f.close()
统计文件里的root关键字一共出现了几次
f= open("f://1.txt")
sum1 =0
for i in f:
if re.findall("root", i):
sum1 += len(re.findall("root", i))
print(sum1)
f.close()
7. 第三方模块之psutil
psutil是一个跨平台库,能够轻松实现获取系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息。它主要应用于系统监控,分析和限制系统资源及进程的管理。
因为是第三方模块,所以需要先使用pip命令安装后才能使用