zoukankan      html  css  js  c++  java
  • 文成小盆友python-num6 -反射 ,常用模块

    本次主要内容:

    • 内容补充
    • python中的反射
    • 常用模块

    一,内容补充:

    利用上次说到的递归的方法来实现阶乘。

    说明:利用函数递归的方法来实现阶乘如: 1*2*3*4*5*6*7

    代码实现如下:

     1 def fuck(num):    
     2     if num == 1 or num == 0:   #这里直接把等于0的情况也写到这里了。
     3         return 1
     4     return  num * fuck(num - 1) #这里用到了递归
     5 
     6 res = fuck(7) 
     7 print(res)
     8 #
     9 #显示如下:
    10 5040
    11 
    12 Process finished with exit code 0

    二。python中的反射

    反射:基于字符串的形式去对象(模块)中操作(寻找,检查,删除,设置)其成员,这里所有的操作都是基于内存来操作的。

    常用的方法:

    • getattr: 寻找对象中的指定成员   
    • hasattr:判断对象中是否有某成员
    • setattr:为对象设置成员
    • delattr:删除对象中的成员

    应用实例:模拟web框架的路由系统,当输入(或者后期的传入)指定的url时,到特定的对象中去执行对应的函数输出特定的内容。

    分析:需要两个文件,一个文件获取用户输入的url,一个文件创建件不同的函数作为模块来等待调用。

    如:所有的功能模块有如下几个:

    # -*- coding:utf-8 -*-
    #Author:wencheng.zhao
    #
    
    def  index():              #定义一个模块当被调用时用于显示首页内容
        print("首页页面内容")
    
    
    def  quit():                 #定义一个模块当被调用时用于显示退出内容 
        print("退出页面内容")
    
    
    def  home():               #定义一个模块当被调用时用于显示主页内容
        print("主页内容")
                

    如上是已经成功创建的模块,现在只要在获取url后根据url的不同来调用不同的模块达到显示不同内容的目的就ok了,如下是一种方法:

     1 import  commons    #导入模块
     2 
     3 while True :
     4     inp = input("please insert your url:") #获取用户的输入
     5     if inp == "index":
     6         commons.index()
     7     elif inp == "quit":
     8         commons.quit()
     9     elif inp == "home":
    10         commons.home()
    11     else:
    12         print("-404-")     ###上面为到用刀if 来判断用户的输入
    13 
    14 
    15 ##  显示如下
    16 please insert your url:index
    17 首页页面内容
    18 please insert your url:home
    19 主页内容
    20 please insert your url:quit
    21 退出页面内容
    22 please insert your url:sss
    23 -404-

    像上面这样就实现了需要的功能。现在问题来了!!! 现实中像这样的页面很多远不止这3个而已,如果还这样if else来判断,虽然是能够实现但是显得十分的low,那么现在的解决方案的来了,python中的反射可以解决此问题:实现如下

    #####反射练习  ---调用commons模块
    import commons
    
    def geturl():
        while True:
            inp = input("请输入要访问的内容:")
            #inp 为字符串类型
    
            if hasattr(commons,inp): #先判断这个模块中是否有这个方法
                func = getattr(commons,inp) 如果有这个方法就把这个函数名获得到
                func()     #执行对应的函数
            else:               
                print("--404--")
    
    
    if __name__ == '__main__':   #这种形式前面没有介绍,后续会补充。。
        geturl()  #调用。
    #显示如下:
    请输入要访问的内容:index
    首页页面内容
    请输入要访问的内容:home
    主页内容
    请输入要访问的内容:quit
    退出页面内容
    请输入要访问的内容:sss
    --404--      

    上面的代码即使模块中有上百个函数,那么调用界面也无需改动代码,这样就实现了。还有需要考虑的情况就是当需要导入的模块并不在同一模块中时,这里就用到了一个额外的import的小知识。

    __import__(): 可以接收字符串来导入,这个模块。如下:

    我在文件manager中创建了一个函数:

    # -*- coding:utf-8 -*-
    #Author:wencheng.zhao
    #
    def guanli ():
        print("管理界面--")

    下面就需要动态的导入需要查找的模块,这时候需要用户同时输入模块的名称和模块中函数的名称来使用,实现如下:

     1 def geturl():
     2     while True:
     3 
     4         inp = input("请输入要访问的内容:")  #输入格式  manager/login
     5         m,u = inp.split("/")   #将获得的字符串分别赋值给m,和u
     6         obj = __import__(m)    # 这里导入的m为字符串,##注意 如果导入的模块不在一级目录上 那么需要用到字符串拼接,并且需要值fromlist = True
     7         if hasattr(obj,u):
     8             func = getattr(obj,u)
     9             func()
    10         else:
    11             print("--404--")
    12 
    13 
    14 if __name__ == '__main__':
    15     geturl()
    16 
    17 ##显示如下:
    18 请输入要访问的内容:commons/index
    19 首页页面内容
    20 请输入要访问的内容:commons/quit
    21 退出页面内容
    22 请输入要访问的内容:commons/home
    23 主页内容
    24 请输入要访问的内容:manager/guanli
    25 管理界面--

    三。基本模块使用补充

    1.sys

    用于提供对python解释器相关的操作

    sys.argv           命令行参数List,第一个元素是程序本身路径
    sys.exit(n)        退出程序,正常退出时exit(0)
    sys.version        获取Python解释程序的版本信息
    sys.maxint         最大的Int值
    sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
    sys.platform       返回操作系统平台名称
    sys.stdin          输入相关
    sys.stdout         输出相关
    sys.stderror       错误相关
    
    ##部分功能如下:
    print(sys.argv)
    print(sys.version)
    print(sys.path)
    print(sys.platform)
    ####分别对应展示
    ['/Users/wenchengzhao/PycharmProjects/s13/day6/temp.py']
    3.5.1 (v3.5.1:37a07cee5969, Dec  5 2015, 21:12:44) 
    [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]
    ['/Users/wenchengzhao/PycharmProjects/s13/day6', '/Users/wenchengzhao/PycharmProjects/s13', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python35.zip', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/plat-darwin', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages']
    darwin

    应用实例:

    利用sys对输出的控制来实现进度条功能:

    import sys
    import time
    
    
    def view_bar(num, total):
        rate = float(num) / float(total)
        rate_num = int(rate * 100)
        balck_num = 100 - rate_num
        r = '
    [%s%s]%d%%' % ("#"*rate_num," "*balck_num,rate_num, )
        sys.stdout.write(r)
        sys.stdout.flush()
    
    
    if __name__ == '__main__':
        for i in range(0, 101):
            time.sleep(0.1)
            view_bar(i, 100)
    
    ##显示如下:
    [###########################################################################                         ]75%

    2.os

    用于提供系统级别的操作:

    os.getcwd()                 获取当前工作目录,即当前python脚本工作的目录路径
    os.chdir("dirname")         改变当前脚本工作目录;相当于shell下cd
    os.curdir                   返回当前目录: ('.')
    os.pardir                   获取当前目录的父目录字符串名:('..')
    os.makedirs('dir1/dir2')    可生成多层递归目录
    os.removedirs('dirname1')   若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
    os.mkdir('dirname')         生成单级目录;相当于shell中mkdir dirname
    os.rmdir('dirname')         删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
    os.listdir('dirname')       列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
    os.remove()                 删除一个文件
    os.rename("oldname","new")  重命名文件/目录
    os.stat('path/filename')    获取文件/目录信息
    os.sep                      操作系统特定的路径分隔符,win下为"\",Linux下为"/"
    os.linesep                  当前平台使用的行终止符,win下为"	
    ",Linux下为"
    "
    os.pathsep                  用于分割文件路径的字符串
    os.name                     字符串指示当前使用平台。win->'nt'; Linux->'posix'
    os.system("bash command")   运行shell命令,直接显示
    os.environ                  获取系统环境变量
    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所指向的文件或者目录的最后修改时间

    3.hashlib模块

    hashlib是个专门提供hash算法的库,现在里面包括md5, sha1, sha224, sha256, sha384, sha512,使用非常简单、方便。 
    md5经常用来做用户密码的存储。而sha1则经常用作数字签名。具体如下:

    import hashlib
    
    ##md5###
    obj = hashlib.md5()
    obj.update(bytes('zhaowencheng',encoding='utf-8'))
    result = obj.hexdigest()
    print(result)
    
    ######## sha1 ########
    
    hash = hashlib.sha1()
    hash.update(bytes('zhaowencheng', encoding='utf-8'))
    print(hash.hexdigest())
    
    # ######## sha256 ########
    hash = hashlib.sha256()
    hash.update(bytes('zhaowencheng', encoding='utf-8'))
    print(hash.hexdigest())
    
    # ######## sha384 ########
    
    hash = hashlib.sha384()
    hash.update(bytes('zhaowencheng', encoding='utf-8'))
    print(hash.hexdigest())
    
    # ######## sha512 ########
    
    hash = hashlib.sha512()
    hash.update(bytes('zhaowencheng', encoding='utf-8'))
    print(hash.hexdigest())

    以上内容使用简单方变,但是能够通过一定的手段如撞库的方法可以对密码进行反解,对于这个问题hashlib提供了自定义添加key来增加安全度:

    import  hashlib
    
    obj = hashlib.md5(bytes("sjdfjskfj",encoding='utf-8'))#可增加人意长度
    obj.update(bytes('zhaowencheng',encoding='utf-8'))
    result = obj.hexdigest()
    print(result)

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

    import hmac
    
    h = hmac.new(bytes('898oaFs09f', encoding="utf-8"))
    h.update(bytes('zhaowencheng', encoding="utf-8"))
    print(h.hexdigest())
    #

    4.re

    就正则表达式(re)本身来讲,他就是一种小型的高度专业化的编程语言,在python中也有内嵌,通过re模块来实现,正则表达式模式被编译成一系列的字节码,然后由c编写的匹配引擎执行。

    字符匹配:

      . 匹配除换行符以外的任意字符
      w 匹配字母或数字或下划线或汉字
      s 匹配任意的空白符
      d 匹配数字
       匹配单词的开始或结束
      ^ 匹配字符串的开始
      $ 匹配字符串的结束

    次数匹配:

      * 重复零次或更多次
      + 重复一次或更多次
      ? 重复零次或一次
      {n} 重复n次
      {n,} 重复n次或更多次
      {n,m} 重复n到m次

    函数:

    1、match(pattern, string, flags=0)

    1 # flags
    2 I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE # ignore case
    3 L = LOCALE = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale
    4 U = UNICODE = sre_compile.SRE_FLAG_UNICODE # assume unicode locale
    5 M = MULTILINE = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline
    6 S = DOTALL = sre_compile.SRE_FLAG_DOTALL # make dot match newline
    7 X = VERBOSE = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments
    8 
    9 flags
    flags

    从起始位置开始根据模型去字符串中匹配指定内容,匹配单个

    • 正则表达式
    • 要匹配的字符串
    • 标志位,用于控制正则表达式的匹配方式
    obj = re.match('d+','d1234ssdff')   #以字母d 开头
    print(obj)
    
    #显示
    None
    
    
    obj = re.match('d+','1234ssdff')
    print(obj)
    
    #显示
    <_sre.SRE_Match object; span=(0, 4), match='1234'>
    
    Process finished with exit code 0
    
    ##如上说明match是从开始位置匹配的。

    2、search(pattern, string, flags=0)

    根据模型去字符串中匹配指定内容,匹配单个

     1 obj = re.search('d+', 'u123u888asf')
     2 if obj:
     3     print (obj.group())
     4 
     5 #显示如下:
     6 123
     7 
     8 Process finished with exit code 0
     9 
    10 #从前往后匹配,只要匹配到则停止向后匹配。

    3、group和groups

    group(N) 返回第N组括号匹配的字符
    m.groups() 返回所有括号匹配的字符,以tuple格式
    a = "123abc456"
    print (re.search("([0-9]*)([a-z]*)([0-9]*)", a).group())
    
    print (re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(0))
    print (re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(1))
    print (re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(2))
    
    print (re.search("([0-9]*)([a-z]*)([0-9]*)", a).groups())
    
    ####显示如下:
    123abc456
    123abc456
    123
    abc
    ('123', 'abc', '456')

    4、findall(pattern, string, flags=0)

    上述两中方式均用于匹配单值,即:只能匹配字符串中的一个,如果想要匹配到字符串中所有符合条件的元素,则需要使用 findall。

    import re
    
    obj = re.findall('d+', 'fa123uu888asf')
    print (obj)
    
    #显示
    #['123', '888']
    
    obj = re.search('d+', 'fa123uu888asf')
    print (obj.group())
    
    #显示
    123

    5、sub(pattern, repl, string, count=0, flags=0)

    用于替换匹配的字符串

    content = "123abc456"
    new_content = re.sub('d+', '这里以前是数字', content)
    # new_content = re.sub('d+', 'sb', content, 1)
    print (new_content)
    
    #显示如下:
    这里以前是数字abc这里以前是数字
    
    Process finished with exit code 0

    6、split(pattern, string, maxsplit=0, flags=0)

    根据指定匹配进行分组

    content = "'1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )'"
    new_content = re.split('*', content)
    # new_content = re.split('*', content, 1)
    print (new_content)
    #以乘号分隔
    ["'1 - 2 ", ' ((60-30+1', '(9-2', '5/3+7/3', '99/4', '2998+10', '568/14))-(-4', '3)/(16-3', "2) )'"]
    
    Process finished with exit code 0
    content = "'1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )'"
    new_content = re.split('[+-*/]+', content)
    # new_content = re.split('*', content, 1)
    print (new_content)
    
    #显示:一 + - *  等任意分隔
    ["'1 ", ' 2 ', ' ((60', '30', '1', '(9', '2', '5', '3', '7', '3', '99', '4', '2998', '10', '568', '14))', '(', '4', '3)', '(16', '3', "2) )'"]
    
    Process finished with exit code 0
    inpp = '1-2*((60-30 +(-40-5)*(9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2))'
    inpp = re.sub('s*','',inpp)
    new_content = re.split('(([+-*/]?d+[+-*/]?d+){1})', inpp, 1)
    print (new_content)
    
    #显示如下:
    ['1-2*((60-30+', '-40-5', '*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))']
    
    Process finished with exit code 0

     

  • 相关阅读:
    WP7应用开发笔记插曲 小心使用MessageBox
    WP7应用开发笔记 继承BitmapSource并使用独立存储来缓存远程的图片
    WP7应用开发笔记(10) 导航
    Bangumi 番組計劃 WP手机客户端发布
    WP7应用开发笔记(17) 提交应用
    WP7应用开发笔记(8) IP输入框控件
    从FLC中学习的设计模式系列结构型模式(2)装饰
    Windows Phone Toolkit for WP8 已经出了
    狂神说HTML笔记
    期待
  • 原文地址:https://www.cnblogs.com/wenchengxiaopenyou/p/5576276.html
Copyright © 2011-2022 走看看