文成小盆友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 = ‘\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下为"\t\n",Linux下为"\n"
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 匹配数字
  \b 匹配单词的开始或结束
  ^ 匹配字符串的开始
  $ 匹配字符串的结束

次数匹配:

  * 重复零次或更多次
  + 重复一次或更多次
  ? 重复零次或一次
  {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
时间: 2024-10-09 17:33:42

文成小盆友python-num6 -反射 ,常用模块的相关文章

文成小盆友python-num7 -常用模块补充 ,python 牛逼的面相对象

本篇内容: 常用模块的补充 python面相对象 一.常用模块补充 1.configparser模块 configparser 用于处理特定格式的文件,起内部是调用open()来实现的,他的使用场景是操作特定格式的文件. 特定的格式如下: # [section1] #节点名称 k1 = v1 #值1 k2 = v2 #值2 [section2] #节点名称 k1 = v1 #值 获取文件中的所有节点 ##configparser 模块使用 #1.获取所有的节点 import configpars

文成小盆友python-num10 socketserver 原理相关。

本节主要内容: 1.IO多路复用 2.多线程多进程 3.小知识点补充(python中作用域相关) 4.socketserver源码分析补充 一.IO多路复用 I/O多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. linux中的io多路复用机制:select,poll,epoll select select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组,当select(

文成小盆友python-num12 Redis发布与订阅补充,python操作rabbitMQ

本篇主要内容: redis发布与订阅补充 python操作rabbitMQ 一,redis 发布与订阅补充 如下一个简单的监控模型,通过这个模式所有的收听者都能收听到一份数据. 用代码来实现一个redis的订阅者何消费者. 定义一个类: import redis class Redis_helper(): def __init__(self): self.__conn = redis.Redis(host='192.168.11.87') #创建一个连接 def pub(self, mes, c

文成小盆友python-num3 集合,函数,-- 部分内置函数

本接主要内容: set -- 集合数据类型 函数 自定义函数 部分内置函数 一.set 集合数据类型 set集合,是一个无序且不重复的元素集合 集合基本特性 无序 不重复 创建集合 #!/bin/env python s1 = {"1","2","3","4"} ##或者 s2 = set() set 提供的功能 1 class set(object): 2 """ 3 set() -> n

文成小盆友python-num2 数据类型、列表、字典

一.先聊下python的运行过程 计算机是不能够识别高级语言的,所以当我们运行一个高级语言程序的时候,就需要一个“翻译机”来从事把高级语言转变成计算机能读懂的机器语言的过程.这个过程分成两类,第一种是编译,第二种是解释.编译型语言在程序执行之前,先会通过编译器对程序执行一个编译的过程,把程序转变成机器语言.运行时就不需要翻译,而直接执行就可以了.最典型的例子就是C语言.解释型语言就没有这个编译的过程,而是在程序运行的时候,通过解释器对程序逐行作出解释,然后直接运行,最典型的例子是Ruby. 当p

文成小盆友python-num4 内置函数

一 .python 内置函数补充 chr()  -- 返回所给参数对应的 ASCII 对应的字符,与ord()相反 # -*- coding:utf-8 -*- # Author:wencheng.zhao a = chr(65) print(a) b = chr(66) print(b) ##输出如下: A B Process finished with exit code 0 ord --返回所给的值在ASCII中对应的数字,与chr()作用相反 # -*- coding:utf-8 -*-

文成小盆友python-num15 - JavaScript基础

一.JavaScript简介 JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能. 二.组成部分 ECMAScript,描述了该语言的语法和基本对象 文档对象模型(DOM),描述处理网页内容的方法和接口. 浏览器对象模型(BOM),描述与浏览器进行交互的方法和接口. 三. Jav

文成小盆友python-num9 socket编程

socket编程 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. Socket的英文原义是“孔”或“插座”.作为BSD UNIX的进程通信机制,取后一种意思.通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信.在Internet上的主机一般运行了多个服务软件,同时提供几种服务.每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务.Socket正如其英文原意那

文成小盆友python-num8 面向对象中的成员,成员修饰符,特殊成员,异常处理,设计模式之单例模式

本节主要内容: 1.面向对象中的成员 2.成员修饰符 3.特殊成员 4.异常处理 5.设计模式之单例模式 一.面向对象中的成员(类的成员) 类的成员总共可以分为3大类,每类中有不同的分支. 1.总述,基本分类 如下图所示: 类成员包括字段,方法,和属性 2.字段 如上图字段分为普通字段和静态字段,两者的使用有区别,但是最大的区别在于两者在内存中的保存位置有区别. 普通字段属于对象而静态字段属于类,在使用过程中谁的字段就由谁来调用. 静态字段和普通字段的定义如下: 在调用时分各自调用 #####类