zoukankan      html  css  js  c++  java
  • Python模块

    模块就是一个以py结尾的python代码文件,(文件名为hello.py,则模块名为hello), 用于实现一个或多个功能(变量,函数,类等)

    模块分为

    1. 标准库(python自带的模块,可以直接调用

    2. 开源模块(第三方模块,需要先pip安装,再调用

    3. 自定义模块(自己定义的模块)

    模块主要存放在/usr/local/lib/python3.6/目录下,还有其它目录下。使用sys.path查看。

    [root@node1 python]# python3
    Python 3.6.6 (default, Oct 10 2020, 11:59:31) 
    [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 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()增加新的模块目录。

    示例: 手动在当前目录下(pycharm当前项目目录)写一个简单模块(名为hello.py)

    hello.py

    def funct1():
        print("funct1")
    
    def funct2():
        print("funct2")
    
    def funct3():
        print("funct3")
    
    if __name__ == "__main__":
        print("haha")   # 直接执行hello.py会执行这段代码
    else:
        print("hehe")   # 通过调用模块的方式会执行这段代码
    

     直接执行会输出haha

     在同目录下写一个1.py来调用hello.py

    import hello    # 调用同目录下的hello模块,相当于执行了hello.py语句
    
    hello.funct1()  # 可以调用hello模块里的funct1()函数
    hello.funct2()  # 可以调用hello模块里的funct2()函数
    hello.funct3()  # 可以调用hello模块里的funct3()函数
    

     执行输出

    :与上面的hello.py同目录下,再写一个1.py来调用hello.py

    :与上面的hello.py同目录下,再写一个1.py来调用hello.

    hehe
    funct1
    funct2
    funct3
    

      解析:调用模块执行hello.py因为不满足条件if __name__ == "__main__":所以执行输出hehe

        其他输出为调用对应函数输出

    模块导入的基本语法

      导入单模块

    import module1
    

     导入多个模块

    import module1,module2,module3
    

      from导入模块所有变量函数

    from  hello import * 
    

      使用这种方法导入执行时无需加hello即直接执行函数即可例如

    from  hello import *   # 调用同目录下的hello模块,相当于执行了hello.py语句
    
    # print(__name__)
    funct1()  # 可以调用hello模块里的funct1()函数
    funct2()  # 可以调用hello模块里的funct2()函数
    funct3()  # 可以调用hello模块里的funct3()函数
    

      from导入模块文件中的部分函数

    from  hello import funct1,funct2 
    

      使用这种方法只能执行导入的函数例如执行以上则无法使用函数funct3

      import语法导入与frim语法导入的区别

      import导入方法相当于是直接解释模块文件

      像from这样的语法导入,相当于是把hello.py里的文件直接复制过来,调用hello.py里的funct1()的话,就不需要hello.funct1()了,而是直接funct1()调用了,如果你本地代码里也有funct1(),就会冲突,后面的会overwrite前面的

    # 代码一
    import hello
    hello.funct1()  # 需要使用模块名调用
    
    # 代码二
    from hello import *
    funct1()    # 无需使用模块名调用
    
    # 代码三
    import hello
    def funct1():
        print("local funct1")
    hello.funct1()  # 调用模块里的函数funct1
    funct1()        # 调用本地的function
    
    # 代码四
    from hello import *
    def funct1():
        print("local funct1")
    hello.funct1()  # hello模块里的funct1与本地的funct1冲突
    funct1()    # 得到的是本地funct1的结果
    

      为了区分本地funct1和导入的hello模块里的function,可以导入的时候做别名

    #
    from hello import funct1 as funct1_hello
    def funct1():
        print("local funct1")
    funct1_hello()
    funct1()
    

      os模块 

      os模块.py

    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])# 得到状态信息的倒数第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"))	# 得到文件绝对路径的目录名,不包括文件即/etc
    print(os.path.basename("/etc/fstab"))	# 得到文件名不包括目录 fstab
    print(os.path.split("/etc/fstab"))	# 把dirname和basename分开结果为tuple类型 ('/etc', 'fstab')
    print(os.path.join("/etc","fstab"))	# 把dirname和basename合并结果为字符串 fstab无需加符合/ /etc/fstab
    
    
    print(os.path.isfile("/tmp/1.txt"))	# 判断是否为文件 结果为bool类型 True
    print(os.path.isabs("1.txt"))		# 判断是否绝对路径 False
    print(os.path.exists("/tmp/11.txt"))	# 判断文件是否存在
    print(os.path.isdir("/tmp"))		# 判断是否目录
    print(os.path.islink("/etc/rc.local"))	# 判断是不是链接文件
    
    # os.rename("/tmp/1.txt","/tmp/11.txt")	# 文件重命名
    # os.remove("/tmp/1.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里的命令,二者有一点小区别:

    [root@node1 模块]# cat os模块2.py 
    import os
    # 下面这两句执行操作都可以成功,如果文件存在则覆盖创建新文件
    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("pwd").read()
    

      练习: 递归找一个目录里的所有链接文件

      方法一

    [root@node1 模块]# cat 查找链接文件.py 
    import os
    
    dir = input("input a directory:")
    
    def find_symlink(dir):
        # 遍历输入文件夹的的目录列表
        # os.listdir(dir)返回的是对应目录的一级文件或者文件夹列表
        for file in os.listdir(dir):
    	# 使用os.path.join把文件夹即返回的列表组成文件的绝对路径
            absfile = os.path.join(dir, file)
    	# 判断如果是链接文件则打印
            if os.path.islink(absfile):
                print("{} is a symlink".format(absfile))
    	# 如果是文件夹则循环调用函数
            elif os.path.isdir(absfile):
                find_symlink(absfile)
    
    # 判断如果输入的是文件夹则调用函数
    if os.path.isdir(dir):
        find_symlink(dir)
    # 如果不是文件夹则提示输入的不是文件夹
    else:
        print("what you input is not a directory")
    

      方法二

    [root@node1 模块]# cat 查找链接文件2.py 
    import os 
    dir = input("inpur a directory:")
    
    command = "find {} -type l".format(dir)
    
    print(command)
    
    if os.path.isdir(dir):
        #print(os.popen(command).read())
        print(os.system(command))
    else:
        print("what you input is not a directory")
    

      练习: 递归查找指定目录的空文件

    [root@node1 模块]# cat 查找空文件.py 
    import os
    
    dir = input("input a directory:")
    
    def find_empty(dir):
        for file in os.listdir(dir):
            absfile = os.path.join(dir, file)
            if os.path.getsize(absfile) == 0:
                print("{} is a empty".format(absfile))
            elif os.path.isdir(absfile):
                find_empty(absfile)
    
    if os.path.isdir(dir):
        find_empty(dir)
    else:
        print("what you input is not a directory")
    

      sys模块

      示例

    [root@node1 模块]# cat sys模块.py 
    import sys, os
    print(sys.path) 	# 模块路径
    print(sys.version)	# python解释器版本信息
    print(sys.platform)	# 操作系统平台名称例如 linux
    
    # sys.argv[0]		# sys.argv[0]等同于shell里的$0,sys.argv[1]等同与shell的$1
    # sys.exit()
    
    # sys.stout.write("hellow world")
    # 执行脚本命令为 python3 sys模块.py df -h
    # 即本次执行sys.argv=["sys模块.py", "df", "-h"]
    # 使用join方法以空格为分割符把切片后的列表["df", "-h"]组合成字符串"df -h"
    command = " ".join(sys.argv[1:])
    print(command)
    # 打印结果为df -h
    
    # 调用系统命令执行df -h 使用read()把执行结果打印
    print(os.popen(command).read())
    

      

      执行输出如下

    [root@node1 模块]# python3 sys模块.py df -h
    ['/nas/nas/scripts/python/模块', '/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']
    3.6.6 (default, Oct 10 2020, 11:59:31) 
    [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
    linux
    df -h
    文件系统                 容量  已用  可用 已用% 挂载点
    devtmpfs                 2.9G     0  2.9G    0% /dev
    tmpfs                    2.9G   16K  2.9G    1% /dev/shm
    tmpfs                    2.9G   54M  2.8G    2% /run
    tmpfs                    2.9G     0  2.9G    0% /sys/fs/cgroup
    /dev/mapper/centos-root   60G  4.7G   56G    8% /
    /dev/sda1                197M  164M   34M   83% /boot
    /dev/mapper/centos-home   20G   33M   20G    1% /home
    /dev/mapper/centos-opt    20G   33M   20G    1% /opt
    tmpfs                    2.9G   24K  2.9G    1% /var/lib/ceph/osd/ceph-2
    tmpfs                    581M     0  581M    0% /run/user/0
    172.16.40.232:/nas       1.0T  215G  809G   21% /nas/nas
    

      random模块

      示例

    import random
    print(random.random())  # 0-1之间随机浮点数
    # 0.12266246730987784
    print(random.uniform(1, 3)) # 1-3之间随机浮点数
    # 2.827372114420131
    print(random.randint(1, 3)) # 1-3之间随机整数
    # 2
    print(random.randrange(1, 3))   # 1-2之间随机整数,不包括3
    # 1
    print(random.randrange(1, 9, 2))    # 1,3,5,7随机最后参数2为步长不包括9
    # 5
    print(random.choice("hello,world")) # 随机字符串里面的一个字符包括,
    # d
    print(random.sample("hello,world", 3))  # 随机取字符串内3个字符组成列表
    # ['d', 'r', 'e']
    list1 = [1, 2, 3, 4, 5]
    random.shuffle(list1)   # 列表随机打乱顺序
    print(list1)
    # [2, 4, 5, 1, 3]
    

      输出如下

    0.1634682227150962
    2.130834169394176
    3
    1
    3
    h
    ['l', 'r', 'e']
    [4, 3, 5, 2, 1]
    

      示例:随机打印四位小写字母

    import random
    # 定义空字符串
    code = ""
    # 循环四次分别随机次数4给小写字母
    for i in range(4):
        # j为随机的小写字母,这个for循环只循环1次
        for j in chr(random.randint(97, 122)):
            # 字符串相加
            code += j
    # 四次循环以后输出结果即四位随机小写字母
    print(code)
    

      示例:随机打印3个字符串,字符串可以是大小写字母及数字

    import random
    code = ""
    for i in range(4):
        j = random.randint(1, 3)
        if j == 1:
            code += chr(random.randint(97, 122))
        elif j == 2:
            code += chr(random.randint(65, 91))
        else:
            code += str(random.randint(0, 9))
    print(code)
    

      re模块

     

       示例

      re.match示例

    [root@node1 模块]# cat re.match.py 
    import re
    print(re.match("aaa", "sdsfaaads")) # re.match匹配开通,结果为None表示匹配未成功
    print(re.match("aaa", "aaasd")) # 有结果输出,表示匹配成功
    # 输出为<_sre.SRE_Match object; span=(0, 3), match='aaa'>
    
    abc=re.match("aaad+","aaa234324bbbbccc")
    print(abc.group())  # 结果为aaa234324 表示匹配到的那部分字符串
    

      re.search示例

    import re
    print(re.search("aaa", "sdfaaasdaaawwwsdf"))    # 有结果输出,表示匹配成功;re.search就是全匹配,而不是开头(但只返回一个匹配的结果);想开头匹配的话可以使用^aaa
    print(re.search("aaad+","aaa111222bbbbcccaaaa333444").group()) # 验证,确实只返回一个匹配的结果,并使用group方法将其匹配结果打印出来
    

      re.findall示例

    [root@node1 模块]# cat re.findall.py 
    import re
    print(re.findall("aaad+", "aaa111222bbbbcccaaaa333444"))   # 没有group方法,本次匹配所有aaa后面带数字,数字个数不限
    # ['aaa111222', 'aaa333444']
    print(re.findall("aaad+|ddd[0-9]+","aaa111222bbbbddd333444")) # 匹配aaa带任意数字 或者ddd带任意数字
    # ['aaa111222', 'ddd333444']
    

      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))# 全替换:成-
    

      替换练习:对输入的关键字进行屏蔽,如笨蛋使用**代替

    [root@node1 模块]# cat 替换练习屏蔽关键字.py 
    import re
    
    input_str = input("Please input:")
    def badword_replace(input_str):
        # 定义屏蔽关键字
        bad_words = ["笨蛋","草","靠","羊驼"]
        # 循环替换,如果遇到关键字替换 "*"*len(word)代表以输入的关键字的长度替换如果输入一个字则是一个*两个字则是两个*
        for word in bad_words:
            input_str = re.sub(word, "*"*len(word), input_str)
        print(input_str)
    
    badword_replace(input_str)
          
    

      

      小结

    match匹配开头
    search匹配整行不一定在开头,但是只匹配第一个
    match和search需要使用group方法打印匹配的字符
    findall匹配所有并且把匹配到的字符以列表形式返回
    

      

      re.split示例

    [root@node1 模块]# cat re.split.py 
    import re
    print(re.split(":", "root:x:0:0:root:/root:/bin/bash"))	# 以:为分隔符分割后面的字符串,并转为列表
    # ['root', 'x', '0', '0', 'root', '/root', '/bin/bash']
    

      split练习:打印文件/etc/passwd以:为分隔符的最后一列

    [root@node1 模块]# cat 打印文件passwd的最后一列.py 
    import re
    f = open("/etc/passwd", "r")
    for line in f:
        # 把每一行以:为分隔符,分割结果为一个列表
        line_list = re.split(":", line)
        # 打印列表最后的元素即最后一列
        print(line_list[-1], end="")
    f.close()
    

      

      练习:使用input输入一个字符串,判断是否为强密码: 长度至少8位,包含大写字母,小写字母,数字和下划线这四类字符则为强密码

      不使用正则的方法

    def check_password(password):
        # 设立flag分别代表统计大小字母,小写字母,数字,下划线
        # 如果出现过一次该对应字符则flag置为False即不再统计一次
        flag1 = True
        flag2 = True
        flag3 = True
        flag4 = True
        # 出现不同字符的次数初始值为0
        count = 0
        if len(password) < 8:
            print("too short")
        else:
            for i in password:
                # 判断出现的大小字母
                if i.isupper() and flag1:
                    count += 1
                    flag1 = False
                    continue
                # 判断出现的小写字母
                elif i.islower() and flag2:
                    count += 1
                    flag2 = False
                    continue
                # 判断出现的数字
                elif i.isdigit() and flag3:
                    count += 1
                    flag3 = False
                    continue
                # 判断出现的下划线
                elif i == "_" and flag4:
                    count += 1
                    flag4 = False
                    continue
            if count >= 4:
                print(count)
                print("strong password")
            else:
                print(count)
                print("weak password")
    password = input("Please input password:")
    check_password(password)
    

      使用正则的方法

    import re
    def check_password(password):
        if len(password) < 8:
            print("Too short")
        else:
            if re.search('[A-Z]', password) and re.search('[a-z]', password) and re.search('[d]', password) and re.search('[_]', password):
                print("Strong password")
            else:
                print("weak password")
    
    password = input("Please input password:")
    
    check_password(password)
    

      解析:re.search匹配整个字符串如果有匹配则有返回,需要同时满足4个返回才输出强密码提示

      练习:文件处理

      1,打印/etc/passw中以daemon开头的行

      2,打印包含root的行

      3,打印文件中出现字符root的次数

    [root@node1 模块]# cat 文件处理.py 
    import re
    # 打开文件
    f = open("/etc/passwd","r")
    #print(f)
    # 定义空列表用来存储以daemon开头的行
    daemon_list = []
    # 定义空列表用来存储包含root的行
    root_list = []
    # 定义空列表用来存储所有root 然后计算列表长度来计算文件中包含root的次数
    root_len = []
    for line in f:
        # 如果开头匹配到daemon则把整行追加至列表
        if re.match("daemon", line):
            daemon_list.append(line)
        # 如果包含root则把整行追加至列表
        elif re.search("root", line):
            root_list.append(line)
    	# 把匹配到的root分割成列表然后累加 列表root_len为一个只包含字符串root的列表
            root_len += re.findall("root", line)
    print("以daemon开头的行")
    for i in daemon_list:
        print(i,end="")
    print("包含root的行")
    for i in root_list:
        print(i,end="")
    print("包含root {}个".format(len(root_len)))
    f.close()
    

      time,datetime,calendar模块

      python有三种时间类型

    时间类型 描述
    struct_tiem 记录时间的年月日时分等
    timestamp时间戳 记录距离1970-01-01 00:00:00有多少秒
    格式化的时间字符串  如2020-11-05 09:00:00

       三种类型之间的转换图

       示例

    import time # 加载时间模块
    
    time.sleep(1)   # 暂停1秒
    
    print(time.localtime()) # 打印本地时间元组 
    # time.struct_time(tm_year=2020, tm_mon=11, tm_mday=5, tm_hour=9, tm_min=58, tm_sec=8, tm_wday=3, tm_yday=310, tm_isdst=0)
    print(time.gmtime())    # 打印时间元组时间为格林威治时间
    # time.struct_time(tm_year=2020, tm_mon=11, tm_mday=5, tm_hour=9, tm_min=58, tm_sec=8, tm_wday=3, tm_yday=310, tm_isdst=0)
    

      对应如下

    序号字段
    0 4位数年 2008
    1 1 到 12
    2 1到31
    3 小时 0到23
    4 分钟 0到59
    5 0到61 (60或61 是闰秒)
    6 一周的第几日 0到6 (0是周一)
    7 一年的第几日 1到366 (儒略历)
    8 夏令时 -1, 0, 1, -1是决定是否为夏令时的旗帜
    print(time.strftime("%Y-%m-%d %H:%M:%S"))   # 打印当前时间,格式化字符串
    # 2020-11-05 10:05:38
    print(time.strftime("%F %T"))   # 打印当前时间,格式化字符串
    # 2020-11-05 10:05:38
    print(time.time())  # 打印当前时间时间戳,离1970年1月1号0点的秒数
    # 1604541938.294913
    

      示例,三种时间格式的转换

    abc = time.localtime()  # 把时间元组赋值给变量abc
    print(time.mktime(abc)) # 把时间元组转换成时间戳,精确到秒
    # 1604542173.0
    print(time.strftime("%Y-%m-%d %H:%M:%S", abc)) # 时间元组转换成时间字符串,自定义格式
    # 2020-11-05 10:11:20
    print(time.asctime(abc))    # 时间元组转换成字符串,默认格式
    # Thu Nov  5 10:13:47 2020
    print(time.strptime("2020-11-05 10:30:25", "%Y-%m-%d %H:%M:%S"))    # 格式化字符串转换成时间元组
    # time.struct_time(tm_year=2020, tm_mon=11, tm_mday=5, tm_hour=10, tm_min=30, tm_sec=25, tm_wday=3, tm_yday=310, tm_isdst=-1)
    print(time.localtime(86400))    # 打印距离1970-01-01 00:00:00时间为86400秒时间的时间元组 即24小说以后的时间元组
    # time.struct_time(tm_year=1970, tm_mon=1, tm_mday=2, tm_hour=8, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=2, tm_isdst=0)
    print(time.gmtime(86400))   # 打印距离1970-01-01 00:00:00时间为86400秒的时间元组,格林威治时间
    
    print(time.ctime(335235))   # 时间戳转换成字符串时间,默认格式
    # Mon Jan  5 05:07:15 1970
    

      datetime,calendar模块

    import datetime, calendar
    print(datetime.datetime.now())  # 打印现在时间
    # 2020-11-05 11:29:17.723348
    print(datetime.datetime.now()+datetime.timedelta(+3))   # 三天后时间
    # 2020-11-08 11:29:17.723348
    print(datetime.datetime.now()+datetime.timedelta(days=-3)) # 三天前时间
    # 2020-11-02 11:29:17.723348
    print(datetime.datetime.now()+datetime.timedelta(hours=5))  # 五小时后时间
    # 2020-11-05 16:29:17.723348
    print(datetime.datetime.now()+datetime.timedelta(minutes=-10))  # 十分钟前时间
    # 2020-11-05 11:19:17.723348
    print(datetime.datetime.now()+datetime.timedelta(weeks=1))  # 一星期之后时间
    # 2020-11-12 11:29:17.723348
    print(calendar.calendar(2020))  # 打印2020年日历
    print(calendar.isleap(2020))    # 判断某年是否是闰年
    # True
    

      练习:打印出昨天的日期(格式要求为YYYY-mm-dd)

    # cat 打印昨天日期.py
    import time
    # 方法一
    # time.strftime("%Y-%m-%d",时间元组)把时间元组格式化成年月日输出
    # time.localtime(时间戳)把时间戳转换成时间元组
    # time.time()-86400 为现在的时间戳减去86400即24销售之前的时间戳
    print(time.strftime("%Y-%m-%d", time.localtime(time.time()-86400)))
    # 方法二
    import datetime
    abc = datetime.datetime.now() + datetime.timedelta(-1)
    print(abc)
    # 2020-11-05 08:52:20.352911
    # str(abc)把时间转化成字符串 2020-11-05 08:52:20.352911
    # 使用split方法以空格为分隔符把字符串转换成列表["2020-11-05", "08:52:20.352911"]
    # 输出列表的第一个元素即格式化的日期
    print(str(abc).split(" ")[0])
    

      练习:做一个倒计时计算现在距离2021年还有多久

    # cat 倒计时
    import time
    while True:
        # 计算2021-01-01 00:00:00的时间戳
        # time.strptime("2021-01-01 00:00:00", "%Y-%m-%d %H:%M:%S")使用格式化方式把时间戳转换成时间元组
        # time.mktime(时间元组) 把时间元组转换成时间戳
        time_stamp_2021 = time.mktime(time.strptime("2021-01-01 00:00:00", "%Y-%m-%d %H:%M:%S"))
        time_stamp_now = time.time()
        # print("2021年1月1日的时间戳为{}".format(int(time_stamp_2021)))
        # print("现在的时间戳为{}".format(int(time_stamp_now)))
        # 计算2021-01-01 00:00:00到现在的时间戳时间相差的秒数并转换成整数赋值给goal_seconds
        goal_seconds = int(time_stamp_2021 - time_stamp_now)
        # 如果相差为0则代表现在的时间戳已经走到2021-01-01 00:00:00了 则退出循环
        if goal_seconds == 0:
            break
        # 否则根据相差时间的秒数计算相差的天时分秒,然后休息1秒钟继续循环
        else:
            print("现在距离2021年1月1日还差{}天{}时{}分{}秒".format(int(goal_seconds/86400), int(goal_seconds%86400/3600), int(goal_seconds%3600/60), int(goal_seconds%60)))
            time.sleep(1)
    

      输出如下

       练习:每隔一秒循环打印2020年的日期格式为(2020-01-01)

      每隔一秒打印2020年日期.py

    # 方法一
    import time
    # 获取2020-01-01的时间元组
    time_tuple_2020 = time.strptime("2020-01-01", "%Y-%m-%d")
    # 获取2020-12-31的时间元组
    time_tuple_2021  = time.strptime("2020-12-31", "%Y-%m-%d")
    # print(time_tuple_2020)
    # print(time.strftime("%Y-%m-%d", time_tuple_2020))
    # 把两个时间元组转换成时间戳
    time_stamp_2020 = time.mktime(time_tuple_2020)
    time_stamp_2021 = time.mktime(time_tuple_2021)
    # print(time_stamp_2020)
    # 循环依次打印日期格式为2020-01-01
    while True:
        if int(time_stamp_2020) >= int(time_stamp_2021):
            break
        else:
            # 格式化输出日期,然后把时间戳+86400即下一天的时间戳
            print(time.strftime("%Y-%m-%d", time.localtime(time_stamp_2020)))
            time_stamp_2020 += 86400
            time.sleep(1)
    

      每隔一秒打印2020年日期2.py

    # 方法二
    import time, datetime
    
    start_time = datetime.datetime.strptime("2020-01-01", "%Y-%m-%d")
    # start_time = 2020-01-01 00:00:00
    delta = datetime.timedelta(days=1)
    
    # str(start_time).split()[0]
    # str(start_time)把日期转换成字符串 2020-01-01 00:00:00
    # str(start_time).split()为把字符串转换成列表 ["2020-01-01", "00:00:00"] 不指定分隔符时分隔符默认为空格
    while True:
        if str(start_time).split()[0] == "2020-01-20":
            break
        else:
            print(str(start_time).split()[0])
            start_time = start_time + delta
            time.sleep(1)
    

      

      第三方模块只psutil

      psutil是一个跨平台库,能够轻松实现获取系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息。它主要应用于系统监控,分析和限制系统资源及进程的管理。因为是第三方模块,所以需要先使用pip命令安装后再能使用

    # pip3.6 install psutil
    # pip3.6 list
    

       windows下需要安装pip3.6才能执行pip安装模块,windows安装pip参考:https://www.cnblogs.com/minseo/p/13947395.html

       使用PyCharm安装模块

     

     

       pastil示例

    import psutil
    # cpu
    print(psutil.cpu_times())   # cpu各时间状态,类型为tuple
    # scputimes(user=26065.78125, system=24281.81250000006, idle=508792.35937499994, interrupt=168.40625, dpc=488.09375)
    print(psutil.cpu_count())   # cpu核数,逻辑核数 类型为int
    # 8
    # memory
    print(psutil.virtual_memory())  # 内存状态,类型为tuple
    # svmem(total=17178800128, available=11681599488, percent=32.0, used=5497200640, free=11681599488)
    print(psutil.swap_memory()) # 交换swap状态,类型为tuple
    # sswap(total=19728936960, used=6905610240, free=12823326720, percent=35.0, sin=0, sout=0)
    # partition
    print(psutil.disk_partitions()) # 查看所有分区信息,类型为列表,列表元素类型为tuple
    # [sdiskpart(device='C:\', mountpoint='C:\', fstype='NTFS', opts='rw,fixed'), sdiskpart(device='D:\', mountpoint='D:\', fstype='NTFS', opts='rw,fixed'), sdiskpart(device='E:\', mountpoint='E:\', fstype='', opts='cdrom')]
    print(psutil.disk_usage("/"))   # 查看分区/信息 类型为tuple
    # sdiskusage(total=34340859904, used=934404096, free=33406455808, percent=2.7)
    print(psutil.disk_usage("c:/")) # 查看分区c:/信息,类型为tuple
    # sdiskusage(total=63260954624, used=37185134592, free=26075820032, percent=58.8)
    # io
    print(psutil.disk_io_counters())    # 查看所有io信息,类型为tuple
    # sdiskio(read_count=376113, write_count=2186178, read_bytes=21786895872, write_bytes=46681673216, read_time=12747, write_time=17433)
    print(psutil.disk_io_counters(perdisk=True)) # 查看每一个磁盘的io信息,类型为dist内部为tuple
    # {'PhysicalDrive0': sdiskio(read_count=374041, write_count=2167981, read_bytes=21706172416, write_bytes=46569422848, read_time=12731, write_time=17417), 'PhysicalDrive1': sdiskio(read_count=2072, write_count=18197, read_bytes=80723456, write_bytes=112250368, read_time=16, write_time=16)}
    # network
    print(psutil.net_io_counters()) # 查看所有网卡的总信息(发包,收包等),类型为tuple
    # snetio(bytes_sent=636645887, bytes_recv=1632356419, packets_sent=2344801, packets_recv=6043099, errin=0, errout=0, dropin=0, dropout=0)
    print(psutil.net_io_counters(pernic=True))  # 查看每一个网卡的信息,类型为dict,内部为tuple
    # {'Ethernet0': snetio(bytes_sent=630656366, bytes_recv=1632356483, packets_sent=2310778, packets_recv=6043100, errin=0, errout=0, dropin=0, dropout=0), 'Loopback Pseudo-Interface 1': snetio(bytes_sent=0, bytes_recv=0, packets_sent=0, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0), 'vEthernet (Default Switch)': snetio(bytes_sent=5989521, bytes_recv=0, packets_sent=34023, packets_recv=0, errin=0, errout=0, dropin=0, dropout=0)}
    
    # process
    print(psutil.pids())    # 查看所有进程id 类型为列表,元素类型为int
    # [0, 4, 68, 340, 368, 392, 400, 424, 432]
    print(psutil.pid_exists(1)) # 判断对应进程是否存在,元素类型为bool
    # False
    print(psutil.Process(0))    # 查看进程相关信息,类型为tuple
    # psutil.Process(pid=0, name='System Idle Process', status='running')
    # user
    print(psutil.users())   # 查看当前用户登录信息,类型为list
    # [suser(name='liuym', terminal=None, host='192.168.1.123', started=1604882731.7022765, pid=None)]
    

      paramiko模块

      安装

    pip3 install paramiko
    

      查看

     

       示例:使用paramiko实现文件的上传和下载

    [root@localhost 模块]# cat paramiko文件上传下载.py 
    import paramiko
    trans = paramiko.Transport(("192.168.1.101", 22))   # 产生连接赋值给trans
    trans.connect(username="root", password="password")   # 连接的用户名和密码
    sftp = paramiko.SFTPClient.from_transport(trans)    # 指定为sftp传输模式
    sftp.get("/etc/fstab", "/tmp/fstab")  # 把对方机器的文件/etc/fstab 下载到本地c:/fstab (Windows目录写法,需要写全文件名,否则执行会报权限错误)
    sftp.put("/etc/fstab", "/tmp/1.txt")  # 把本机文件上传至远程连接主机对应目录,同理目标文件需要写全文件名,可以与原文件名不一致
    trans.close()
    

      运行没有返回,会把远程主机的文件下载以及把本地文件上传至服务器192.168.1.101

      上面示例把密码写到代码中取,不安全,下面使用免密登录,需要事先设置好ssh免密

    ssh-keygen 
    ssh-copy-id -i 192.168.1.102
    ssh 192.168.1.102
    

      

    [root@localhost 模块]# cat paramiko文件上传下载2.py 
    import paramiko
    trans = paramiko.Transport(("192.168.1.102", 22))   # 产生连接赋值给trans
    
    private_key=paramiko.RSAKey.from_private_key_file("/root/.ssh/id_rsa")
    trans.connect(username="root",pkey=private_key)# 提前使用ssh-keygen做好免密登录
    sftp = paramiko.SFTPClient.from_transport(trans)    # 指定为sftp传输模式
    sftp.get("/etc/fstab", "/tmp/fstab2")  # 把对方机器的文件/etc/fstab 下载到本地c:/fstab (Windows目录写法,需要写全文件名,否则执行会报权限错误)
    sftp.put("/etc/fstab", "/tmp/1.txt")  # 把本机文件上传至远程连接主机对应目录,同理目标文件需要写全文件名,可以与原文件名不一致
    trans.close()
    

      示例:使用paramiko远程登陆实现执行命令操作

    [root@localhost 模块]# cat paramiko远程登陆操作.py
    import paramiko
    
    ssh = paramiko.SSHClient() # 创建一个客户端连接实例
    
    private_key = paramiko.RSAKey.from_private_key_file("/root/.ssh/id_rsa")
    
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)  # 加了这一句,如果第一次ssh连接要你输入yes,也不用输入了
    
    ssh.connect(hostname="192.168.1.102",port=22,username="root",pkey=private_key)# 把password=123456换成pkey=private_key
    
    stdin,stdout,stderr = ssh.exec_command("touch /tmp/321")
    
    cor_res = stdout.read()	# 标准输出赋值
    err_res = stderr.read()	# 错误输出赋值
    
    if cor_res:
        result = cor_res
    else:
        result = err_res
    
    
    print(cor_res.decode())	# 网络传输的是二进制需要使用decode输出
    print(err_res.decode())	
    ssh.close()	# 关闭连接
    

      执行后会在对应的主机创建文件,但是本次使用的命令是touch没有输出,如果使用其他命令例如pwd则会输出/root如果使用一个没有的命令则会输出错误输出

       练习:写一个程序,针对一批次主机执行命令然后查看返回结果

    [root@localhost 模块]# cat paramiko综合.py 
    import paramiko
    
    def remote_exec_command(ip, command, port=22):
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)
        private_key = paramiko.RSAKey.from_private_key_file("/root/.ssh/id_rsa")
        ssh.connect(hostname=ip, port=port,username="root",pkey=private_key)
    
        stdin, stdout, stderr = ssh.exec_command(command)
        print(stdout.read().decode(), end="")
        print(stderr.read().decode(), end="")
        ssh.close()
    
    
    # remote_exec_command("192.168.1.102","df -h")
    
    def read_ip_port():
        cmd = input("input what command you want do:")
        f = open("/tmp/1.txt","r")
        for line in f:
            read_ip = line.strip().split(":")[0] # 去掉空格和回车然后转换成列表["192.168.1.120", "22"]
            read_port = line.strip().split(":")[1]
            remote_exec_command(read_ip, cmd, read_port)
        f.close()
            
    read_ip_port()
    

      其中文本/tmp/1.txt存储了主机的用户名和端口号

    [root@localhost 模块]# cat /tmp/1.txt 
    192.168.1.102:22
    192.168.1.102:22
    

      执行输入需要执行的命令

    :与上面的hello.py同目录下,再写一个1.py来调用

  • 相关阅读:
    struts2.16 启动报错解决方案 at com.opensymphony.xwork2.util.FileManager$FileRevision.needsReloading(FileManager.java:209)
    多线程的概念
    JQuery Easy Ui 可装载组合框 ComboBox
    Spring 3.0 基于 Annotation 的依赖注入实现
    JQuery Easy Ui dataGrid 数据表格
    数据库中 对原有字段进行字符串追加处理
    1.Python知识点补充
    转跨站脚本攻击详解
    Wiz笔记
    ASP.NET角色管理的基本配置
  • 原文地址:https://www.cnblogs.com/minseo/p/13905281.html
Copyright © 2011-2022 走看看