一、递归,阶乘
递归之实例:
def func(num):
"""
1*2*3*4*5... 计算类型形式的阶乘
:param num: 计算阶乘的最大值
:return: 7 * (7 - 1)
"""
# 如果参数为1,直接返回1
if num == 1:
return 1
# 否则返回2 * (2 - 1)
return num * func(num - 1)
x = func(5)
print(x)
# ########print###########
120
print(1 * 2 * 3 * 4 * 5)
# ########print###########
120
二、反射
反射关键:
反射: 基于字符串的形式去对象(模块)中操作其成员
基于内存操作的
delattr 删除成员
setattr 设置成员
getattr 获取成员
hasattr 检查成员
学习反射之前先了解一下下面的知识
# 定义一个函数名为f1
def f1():
print('F1')
# 字符串f1
"f1"
# 那么函数名的f1与字符串的f1是否一样
答案是不一样
f1 是 函数名,代表整个函数体
"f1"是 字符串,仅代表字符串本身
现在以一个实例来学习反射

#!/bin/bin/env python
# -*-coding:utf-8 -*-
def login():
print("登录界面")
def loginout():
print("退出界面")
def index():
print("主界面")
先对比俩个图

代码块

#!/bin/bin/env python
# -*-coding:utf-8 -*-
def run():
import reflection
select = input("请输入你要访问的URL:")
if select == 'login':
reflection.login()
elif select == 'loginout':
reflection.loginout()
elif select == 'index':
reflection.index()
else:
print("404")
run()
# ########################
"""
请输入你要访问的URL:loginout
退出界面
请输入你要访问的URL:login
登录界面
请输入你要访问的URL:index
主界面
请输入你要访问的URL:inde
404
"""

代码块

#!/bin/bin/env python
# -*-coding:utf-8 -*-
def runs():
import reflection
res = input("输入你要访问的URL:")
if hasattr(reflection, res):
func = getattr(reflection, res)
func()
else:
print("404")
runs()
# #######################
'''
输入你要访问的URL:index
主界面
输入你要访问的URL:login
登录界面
输入你要访问的URL:loginout
退出界面
输入你要访问的URL:3434
404
'''
以上呢是在同一个模块中做的,那如果是在不同模块中要怎么使用呢???

代码块
# __import__("day6.%s" % m, fromlist=True)
def runs():
# reflection/login
res = input("输入你要访问的URL:")
m, s = res.split("/")
obj = __import__("day6.%s" % m, fromlist=True) # 可以在不同级目录中使用
# print(obj)
# <module 'day6.str_module' from 'E:\\PyCharm4.5.2\\PyCharm 文件\\day6\\str_module.py'>
# obj = __import__("day6.%s" % m,)
# print(obj)
# <module 'day6' from 'E:\\PyCharm4.5.2\\PyCharm 文件\\day6\\__init__.py'>
if hasattr(obj, s):
func = getattr(obj, s)
func()
else:
print("404")
runs()
# #######################
'''
输入你要访问的URL:reflection/index
主界面
输入你要访问的URL:reflection/login
登录界面
输入你要访问的URL:reflection/loginout
退出界面
输入你要访问的URL:reflection/3434
404
'''
三、模块
特殊变量
1 # 将文件中的注释添加到文档中 2 __doc__ 3 # .pyc 字节码在哪个路径,然后打印出来 4 __cached__ 5 # 当前py文件所在的路径 6 __file__ 7 # 当前py文件中返回None,被调用输出当前文件的上一级目录名 8 __package__ 9 # 只有执行当前文件的时候,当前文件的特殊变量 __name__ == "__main__" 10 __name__
一个进度条实例
import time
import sys
def view_bar(num, total):
rate = num / total
rate_num = rate * 100
# \r 表示替换这个位置
r = "\r%s%d%%" % (['=' * num], rate_num,)
# 输出不加换行符
sys.stdout.write(r)
# 实时刷新
sys.stdout.flush()
# print(r)
# view_bar(1, 100)
for i in range(1, 101):
view_bar(i, 100)
time.sleep(0.1)
1、hashlib模块
用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
import hashlib
obj = hashlib.md5(bytes('jdffjdslf', encoding='utf-8'))
obj.update(bytes("123", encoding='utf-8'))
result = obj.hexdigest()
##########################################################
print(result)
# e6da8580c5b4c3a6e1b0da4957abd271
import hashlib
obj = hashlib.sha1()
obj.update(bytes('123', encoding='utf-8'))
result = obj.hexdigest()
##############################################################
print(result)
# 40bd001563085fc35165329ea1ff5c5ecbdbbeef
import hashlib
obj = hashlib.sha256()
obj.update(bytes('123', encoding='utf-8'))
result = obj.hexdigest()#######################################################################
print(result)
# a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3
import hashlib
obj = hashlib.sha512()
obj.update(bytes('123', encoding='utf-8'))
result = obj.hexdigest()
#######################################################################
print(result)
# 3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2
以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。
import hashlib
obj = hashlib.md5(bytes('rain', encoding='utf-8'))
obj.update(bytes("123", encoding='utf-8'))
result = obj.hexdigest()
###########################
print(result)
# b19575adf69aca85fb4c1523d258a885
python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密
import hmac
obj = hmac.new(bytes("rain", encoding='utf8'))
obj.update(bytes("123", encoding='utf8'))
result = obj.hexdigest()
###########################
print(result)
# 1895606979c7fcd5cf926f46a36d096a可以与hashlib.md5()加密之后做一个对比
2、正则表达式
正则也是一种小型的语言
re模块用于对python的正则表达式的操作
1)导入re模块
import re
2)正则表达式匹配模式
| 模式 | 描述 |
|---|---|
| ^ | 匹配字符串的开头 |
| $ | 匹配字符串的末尾。 |
| . | 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。 |
| [...] | 用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k' |
| [^...] | 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。 |
| re* | 匹配0个或多个的表达式。 |
| re+ | 匹配1个或多个的表达式。 |
| re? | 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式 |
| re{ n} | |
| re{ n,} | 精确匹配n个前面表达式。 |
| re{ n, m} | 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式 |
| a| b | 匹配a或b |
| (re) | G匹配括号内的表达式,也表示一个组 |
| (?imx) | 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。 |
| (?-imx) | 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。 |
| (?: re) | 类似 (...), 但是不表示一个组 |
| (?imx: re) | 在括号中使用i, m, 或 x 可选标志 |
| (?-imx: re) | 在括号中不使用i, m, 或 x 可选标志 |
| (?#...) | 注释. |
| (?= re) | 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。 |
| (?! re) | 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功 |
| (?> re) | 匹配的独立模式,省去回溯。 |
| \w | 匹配字母数字 |
| \W | 匹配非字母数字 |
| \s | 匹配任意空白字符,等价于 [\t\n\r\f]. |
| \S | 匹配任意非空字符 |
| \d | 匹配任意数字,等价于 [0-9]. |
| \D | 匹配任意非数字 |
| \A | 匹配字符串开始 |
| \Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。c |
| \z | 匹配字符串结束 |
| \G | 匹配最后匹配完成的位置。 |
| \b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 |
| \B | 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 |
| \n, \t, 等. | 匹配一个换行符。匹配一个制表符。等 |
| \1...\9 | 匹配第n个分组的子表达式。 |
| \10 | 匹配第n个分组的子表达式,如果它经匹配。否则指的是八进制字符码的表达式。 |
3)正则表达式修饰符 - 可选标志
| 修饰符 | 描述 |
|---|---|
| re.I | 使匹配对大小写不敏感 |
| re.L | 做本地化识别(locale-aware)匹配 |
| re.M | 多行匹配,影响 ^ 和 $ |
| re.S | 使 . 匹配包括换行在内的所有字符 |
| re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
| re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理 解。 |
正则详解
1、match(pattern, string, flags=0)
从起始位置开始根据模型去字符串中匹配指定内容,匹配单个
- 正则表达式
- 要匹配的字符串
- 标志位,用于控制正则表达式的匹配方式
import re
obj = re.match('\d+', '123djfjjf')
print(obj.group())
# 123
obj = re.match('\d+', 'dj123fjjf')
print(obj.group())
# 由于match只匹配开始位置,所以这里会报错

# flags I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE # ignore case L = LOCALE = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale U = UNICODE = sre_compile.SRE_FLAG_UNICODE # assume unicode locale M = MULTILINE = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline S = DOTALL = sre_compile.SRE_FLAG_DOTALL # make dot match newline X = VERBOSE = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments
2、search(pattern, string, flags=0)
根据模型去字符串中匹配指定内容,匹配单个
import re
obj = re.search('\d+', 'dfjs123456')
print(obj.group())
# 123456
obj = re.search('\d+', '456dfjs123456')
print(obj.group())
# 456
3、findall(pattern, string, flags=0)
上述两中方式均用于匹配单值,即:只能匹配字符串中的一个,如果想要匹配到字符串中所有符合条件的元素,则需要使用 findall。
import re
obj = re.findall('\d+', '123jfj123456')
print(obj)
# ['123', '123456']
obj = re.findall('\d+', 'afsf789sjfj123456')
print(obj)
# ['789', '123456']
4、sub(pattern, repl, string, count=0, flags=0)
用于替换匹配的字符串
import re
content = "123abc456"
# 将所有数字替换成abc
new_content = re.sub('\d+', 'abc', content)
print(new_content)
# abcabcabc
content = "123abc456"
# 只替换第一个匹配到的数字
new_content = re.sub('\d+', 'sb', content, 1)
print(new_content)
# sbabc456
content = "123ab123c456"
# 只替换前二个匹配到的数字
new_content = re.sub('\d+', 'rain', content, 2)
print(new_content)
# rainabrainc456
5、split(pattern, string, maxsplit=0, flags=0)
根据指定匹配进行分组
import re
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)
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) )'"]
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, 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) )'"]
import re
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) )'"]
import re
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里面的任意空白字符替换为空
inpp = re.sub('\s*', '', inpp)
# new_content = re.split('\(([\+\-\*\/]?\d+[\+\-\*\/]?\d+){1}\)', inpp, 1)
new_content = re.split('\(([^()]+)\)', 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))']
6、group和groups
import re
a = "123abc456"
print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group())
# 123abc456
print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(0))
# 123abc456
print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(1))
# 123
print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(2))
# abc
print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).groups())
# ('123', 'abc', '456')
| group(num=0) | 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 |
| groups() | 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。 |
字符类
| 实例 | 描述 |
|---|---|
| [Pp]ython | 匹配 "Python" 或 "python" |
| rub[ye] | 匹配 "ruby" 或 "rube" |
| [aeiou] | 匹配中括号内的任意一个字母 |
| [0-9] | 匹配任何数字。类似于 [0123456789] |
| [a-z] | 匹配任何小写字母 |
| [A-Z] | 匹配任何大写字母 |
| [a-zA-Z0-9] | 匹配任何字母及数字 |
| [^aeiou] | 除了aeiou字母以外的所有字符 |
| [^0-9] | 匹配除了数字外的字符 |
正则例子:
匹配手机号
import re
phone_str = "hey my name is alex, and my phone number is 13651054607, please call me if you are pretty!"
# 完全匹配11位电话号码
m = re.search('([\d]{11})', phone_str)
print(m.group())
# 13651054607
phone_str2 = "hey my name is alex, and my phone number is 18651054604, please call me if you are pretty!"
# 匹配以1开头并且第二位为[358]的11位电话号话
m = re.search('(1)([358]\d{9})', phone_str2)
print(m.group())
# 18651054604
匹配IP V4
import re
ip_addr = "inet 192.168.60.223 netmask 0xffffff00 broadcast 192.168.60.255"
m = re.search('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', ip_addr)
print(m.group())
# 192.168.60.223
ip_addr = "inet 192.168.60.223 netmask 0xffffff00 broadcast 192.168.60.255"
m = re.findall('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', ip_addr)
print(m)
# ['192.168.60.223', '192.168.60.255']
分组匹配地址
import re contactInfo = 'Oldboy School, Beijing Changping Shahe: 010-8343245' m = re.search(r'(\w+), (\w+) (\S+)', contactInfo) # 分组 # School, Beijing Changping m = re.search(r'(\w+) (\w+): (\S+)', contactInfo) # 分组 # Changping Shahe: 010-8343245 print(m.group()) # School, Beijing Changping print(m.group(0)) # School, Beijing Changping print(m.group(1)) # School print(m.group(2)) # Beijing print(m.group(3)) # Changping
匹配email
import re
email = "rain_linux@163.com http://www.oldboyedu.com"
# \w中包含_下划线
m = re.search(r"[\w0-9.a-z]{0,26}@[0-9.a-z]{0,20}.[0-9a-z]{0,8}", email)
print(m.group())
# rain_linux@163.com
未完待续!!!
来源:https://www.cnblogs.com/yxy-linux/p/5578428.html
