• Python--模块之time、random、os、hashlib


    今天开始模块。

    首先补充 __init__.py
          在python模块的每一个包中,都有一个__init__.py文件(这个文件定义了包的属性和方法)然后是一些模块文件和子目录,假如子目录中也有__init__.py 那么它就是这个包的子包了。当你将一个包作为模块导入(比如从 xml 导入 dom )的时候,实际上导入了它的__init__.py 文件。

          一个包是一个带有特殊文件 __init__.py 的目录。__init__.py 文件定义了包的属性和方法。其实它可以什么也不定义;可以只是一个空文件,但是必须存在。如果 __init__.py 不存在,这个目录就仅仅是一个目录,而不是一个包,它就不能被导入或者包含其它的模块和嵌套包。

          __init__.py 中还有一个重要的变量,叫做__all__。我们有时会使出一招“全部导入”。这时 import 就会把注册在包__init__.py 文件中 __all__ 列表中的子模块和子包导入到当前作用域中来。

    Python查找模块的路径

           运行Python应用或引用Python模块,Python解释器要有一个查找的过程。可以通过设置一个环境变量PYTHONPATH为Python增加一个搜索路径,以方便查找到相关Python模块,这与众多应用程序需要设置一个系统环境变量的道理是一样的。在命令行中可以通过以下命令设置:

    C:UsersAdministrator>set PYTHONPATH=E:/Project/Python/ModuleAndPackage/

    进入Python环境后可以,通过Python的sys.path属性获得当前搜索路径的配置,可以看到之前我们设置的路径已经在当前搜索路径中了。

    也可以通过sys模块的append方法在Python环境中增加搜索路径。

    Python中的模块和包

            每个.py文件都是可以认为是一个Python模块,.py文件中可以包含类、方法、变量和常量(Python还没有严格意义上的常量,只是约定大写的变量作为常量),文件内也可以直接写所有的逻辑语句并在加载时从上之下直接执行,这与其他解释型语言是类似的。

            引用一个模块,就要建立运行它的上下文环境。我们先设置一个环境变量PYTHONPATH,以便Python解释器找到.py模块,然后import 模块名字,即可访问其中的方法或变量。或者使用from关键字直接导入模块内的属性或方法。

    一、 time模块

    表示时间我们通常用三种形式:

    • 时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
    • 格式化的时间字符串(Format String)
    • 结构化的时间(struct_time):struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)
    import time
    print(time.time()) #时间戳:1498025310.887425
    print(time.strftime("%Y-%m-%d %X")) #格式化的时间字符串:2017-06-21 14:08:30
    print(time.localtime()) #本地时区的struct_time
    print(time.gmtime()) #UTC时区的struct_time
    结果:
    1498025310.887425
    2017-06-21 14:08:30
    time.struct_time(tm_year=2017, tm_mon=6, tm_mday=21, tm_hour=14, tm_min=8, tm_sec=30, tm_wday=2, tm_yday=172, tm_isdst=0)
    time.struct_time(tm_year=2017, tm_mon=6, tm_mday=21, tm_hour=6, tm_min=8, tm_sec=30, tm_wday=2, tm_yday=172, tm_isdst=0)

    三者的转换关系:

    计算机认识的时间只能是'时间戳'格式,而程序员可处理的或者说人类能看懂的时间有: '格式化的时间字符串','结构化的时间'。

    import time
    print(time.time())
    print(time.localtime())
    
    #将结构化的时间转换为格式化的字符串时间
    print(time.strftime("%Y-%m-%d %X", time.localtime()))
    
    #将结构化的时间转换为时间戳
    print(time.mktime(time.localtime()))
    
    #将时间戳转换为结构化的时间
    print(time.localtime(1498025310))
    
    #将格式化的字符串时间转换为结构化的时间
    print(time.strptime("2017-06-21 16:55:36", "%Y-%m-%d %X"))
    结果:
    1498035729.0793116
    time.struct_time(tm_year=2017, tm_mon=6, tm_mday=21, tm_hour=17, tm_min=2, tm_sec=9, tm_wday=2, tm_yday=172, tm_isdst=0)
    2017-06-21 17:02:09
    1498035729.0
    time.struct_time(tm_year=2017, tm_mon=6, tm_mday=21, tm_hour=14, tm_min=8, tm_sec=30, tm_wday=2, tm_yday=172, tm_isdst=0)
    time.struct_time(tm_year=2017, tm_mon=6, tm_mday=21, tm_hour=16, tm_min=55, tm_sec=36, tm_wday=2, tm_yday=172, tm_isdst=-1)

     

    #将结构化的时间转换为字符串时间
    print(time.asctime(time.localtime()))
    print(time.asctime()) #如果没有参数,将会将time.localtime()作为参数传入。
    print('我是分割线---------------')
    #将时间戳转换为字符串时间
    print(time.ctime(time.time()))
    print(time.ctime()) #如果没有参数,将会将time.time()作为参数传入。
    结果:
    Wed Jun 21 22:19:16 2017
    Wed Jun 21 22:19:16 2017
    我是分割线---------------
    Wed Jun 21 22:19:16 2017
    Wed Jun 21 22:19:16 2017

    二、 random模块

    import random 
    print(random.random()) #(0,1)----float 大于0且小于1之间的小数 结果:0.3869734571949781
    print(random.randint(1,3)) #[1,3] 大于等于1且小于等于3之间的整数 结果:3
    print(random.randrange(1,3)) #[1,3) 大于等于1且小于3之间的整数 结果:1
    print(random.choice([1,'abc',['a',23,'world']])) #1或者'abc'或者['a',23,'world'] 结果:['a', 23, 'world'] 
    print(random.sample([1,'abc',['a',23,'world']],2)) #列表元素任意2个组合 结果:[['a', 23, 'world'], 'abc'] 
    print(random.uniform(1,3)) #大于1小于3的小数 结果:2.164429956472153 
    
    l = [1,2,4,5,9]
    random.shuffle(l)
    print(l) #打乱l的顺序,相当于"洗牌"[5, 2, 9, 4, 1]

    生成随机验证码实例:

    import random
    def verify_code():
        res = ""
        for i in range(5):
            res1 = random.randint(1,9)
            res2 = chr(random.randint(97,122))
            res3 = chr(random.randint(65,90))
            res4 = random.choice([str(res1),res2,res3])
            res +=res4
        return res
    
    print(verify_code())
    结果:
    IcglH

    三 、os模块

    os模块是与操作系统交互的一个接口

    需要掌握的应用:

    os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
    os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd
    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.path.abspath(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.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
    os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间
    os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间
    os.path.getctime(path) 回path所指向的文件或者目录的创建时间 os.path.getsize(path) 返回path的大小

    选择性掌握的应用:

    os.path.split(path)  将path分割成目录和文件名二元组返回
    os.path.isabs(path)  如果path是绝对路径,返回True
    os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False
    os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False

    示例:

    import os
    print(os.getcwd())
    os.chdir(r'C:UsersAdministratorPycharmProjectsuntitled4')
    print(os.getcwd())
    print('我是分割线--------')
    print(os.listdir(r'C:UsersAdministratorPycharmProjectsuntitled4a'))
    print('我是分割线--------')
    res = os.stat(r'C:UsersAdministratorPycharmProjectsuntitled4acd')
    print(res)
    print(res.st_ctime)
    print('我是分割线--------')
    dirname,basename=os.path.split(r'C:UsersAdministratorPycharmProjectsuntitled4aa.txt')
    print(dirname)
    print(basename)
    print('我是分割线--------')
    s1=r'C:UsersAdministratorPycharmProjectsuntitled4ac'
    s2=r'c.txt'
    res=os.path.join(s1,s2)
    print(res)
    结果:
    C:UsersAdministratorPycharmProjectsuntitled
    C:UsersAdministratorPycharmProjectsuntitled4
    我是分割线--------
    ['a.txt', 'b']
    我是分割线--------
    os.stat_result(st_mode=16895, st_ino=7881299347966345, st_dev=1221946964, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1498052199, st_mtime=1498052199, st_ctime=1498052199)
    1498052199.7336605
    我是分割线--------
    C:UsersAdministratorPycharmProjectsuntitled4a
    a.txt
    我是分割线--------
    C:UsersAdministratorPycharmProjectsuntitled4acc.txt

    四、hashlib模块

    hash:一种算法 ,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
    三个特点:
    1.内容相同则hash运算结果相同,内容稍微改变则hash值则变
    2.不可逆推
    3.相同算法:无论校验多长的数据,得到的哈希值长度固定。

    import hashlib
     
    m=hashlib.md5()# m=hashlib.sha256()
     
    m.update('hello'.encode('utf8'))
    print(m.hexdigest())  #5d41402abc4b2a76b9719d911017c592
     
    m.update('alvin'.encode('utf8'))
     
    print(m.hexdigest())  #92a7e713c30abbb0319fa07da2a5c4af
     
    m2=hashlib.md5()
    m2.update('helloalvin'.encode('utf8'))
    print(m2.hexdigest()) #92a7e713c30abbb0319fa07da2a5c4af
    
    '''
    注意:把一段很长的数据update多次,与一次update这段长数据,得到的结果一样
    但是update多次为校验大文件提供了可能。
    '''

    以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。

    import hashlib
     
    # ######## 256 ########
     
    hash = hashlib.sha256('898oaFs09f'.encode('utf8'))
    hash.update('alvin'.encode('utf8'))
    print (hash.hexdigest())#e79e68f070cdedcfe63eaf1a2e92c83b4cfb1b5c6bc452d214c1b7e77cdfd1c7

    实例:模拟撞库破解密码

    import hashlib
    passwds=[
        'alex3714',
        'alex1313',
        'alex94139413',
        'alex123456',
        '123456alex',
        'a123lex',
        ]
    def make_passwd_dic(passwds):
        dic={}
        for passwd in passwds:
            m=hashlib.md5()
            m.update(passwd.encode('utf-8'))
            dic[passwd]=m.hexdigest()
        return dic
    
    def break_code(cryptograph,passwd_dic):
        for k,v in passwd_dic.items():
            if v == cryptograph:
                print('密码是===>33[46m%s33[0m' %k)
    
    cryptograph='aee949757a2e698417463d47acac93df'
    break_code(cryptograph,make_passwd_dic(passwds))
    
    模拟撞库破解密码

    python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 进行进一步的处理然后再加密:

    1 import hmac
    2 h = hmac.new('alvin'.encode('utf8'))
    3 h.update('hello'.encode('utf8'))
    4 print (h.hexdigest())#320df9832eab4c038b6c1d7ed73a5940
  • 相关阅读:
    c#委托 事件 lamda 简写
    c#委托 事件 lamda 简写
    SQL Server 存储过程返回结果集的几种方式
    SQL Server 存储过程返回结果集的几种方式
    C# WinForm 慎用 override CreateParams 来重载窗体的一些特性
    C# WinForm 慎用 override CreateParams 来重载窗体的一些特性
    sqlserver临时表的生命周期到底有多长
    基础练习 回文数
    基础练习 回文数
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1123:图像相似度
  • 原文地址:https://www.cnblogs.com/metianzing/p/7060716.html
Copyright © 2020-2023  润新知