zoukankan      html  css  js  c++  java
  • day5(老男孩-Python3.5-S14期全栈开发)

    作者:赵俊            发布日期:2020/09/03

    三、模块定义、导入、优化详解1

    1、定义

      模块:用来从逻辑上组织python代码,本质就是.py结尾的一个python文件

      包:从逻辑上组织模块,本质就是一个目录(必须带有一个__init__.py文件)

    2、导入方法

      导入单个模块>>>>>import 模块名

      导入多个模块>>>>>import 模块名1,模块名2,............

      以上导入使用时格式,模块名.变量或函数名()

      直接导入所有>>>>>from 模块名 import *(不建议这么使用,会和本身代码中的函数冲突)

      直接导入函数或变量>>>>>from 模块名 import 函数名

      直接导入函数或变量>>>>>from 模块名 import 函数名 as 别名,调用时使用别名,避免冲突

      以上导入使用时格式,直接使用变量或函数名()

    3、import本质

      导入模块的本质就是把python文件解释一遍

      导入包的本质就是执行包下面的init.py文件

    四、模块定义、导入、优化详解2

    在__init__.py文件里直接使用import好像不起作用,使用from . import module可以导入模块

    导入优化 -----------from 模块名 import 函数名,使用这个避免了重复查找模块,提高程序效率

    五、内置模块详解之time与datetime模块

     python模块的分类:

      标准库,系统自带的模块

      开源模块,程序爱好者开发并开源的模块

      自定义模块,自己写的模块

    1、time模块

      在python中有三种表示时间的方式:

        1)时间戳,是当下时间与1970年1月1日零时零分零秒的一个时间差

        2)格式化的时间字符串

        3)元祖(共九个元素) 返回值分别代表,年/月/日/时/分/秒/一周第几天/一年第几天/夏令时

     1 # Author:ZHJ
     2 import time
     3 print(time.sleep(1))  # 休眠几秒
     4 #返回元祖的语句
     5 print("返回元祖------------------------------------------------------")
     6 print(time.gmtime())  # 传入时间戳参数,返回元祖形式时间,转换的时间是UTC时间,不是当地时间
     7 print(time.localtime())  # 传入时间戳参数,返回元祖形式时间,转换的时间是本地时间(UTC+8)
     8 print(time.strptime("2803-2>>12","%Y-%m>>%d"))  # 传入需要的格式化的字符串时间和格式标注,返回元祖
     9 print("返回秒------------------------------------------------------")
    10 #返回秒的语句
    11 print(time.timezone)  # 本地标准时间与标准UTC的时间差,单位为秒,除以3600就为时区,负数为东,正数为西
    12 print(time.altzone)  # 本地夏令时间与标准UTC的时间差,单位为秒
    13 print("返回时间戳------------------------------------------------------")
    14 #返回时间戳
    15 print(time.time())  # 获取时间戳
    16 x = time.localtime()
    17 print(time.mktime(x))  # 传入元祖,返回时间戳
    18 print("返回格式化字符串------------------------------------------------------")
    19 #返回格式化字符串时间
    20 print(time.strftime("%Y-%m>>%d", x))  # 传入需要的标准格式和元祖,返回格式化的字符串时间
    21 print(time.asctime())  # 传入元祖,返回格式化字符串时间,没有传变量使用当前时间元祖
    22 print(time.ctime())  # 传入秒,返回格式化字符串时间,没有传变量使用当前时间秒
    23 """
    24     strftime格式化
    25     %Y  Year with century as a decimal number.
    26     %m  Month as a decimal number [01,12].
    27     %d  Day of the month as a decimal number [01,31].
    28     %H  Hour (24-hour clock) as a decimal number [00,23].
    29     %M  Minute as a decimal number [00,59].
    30     %S  Second as a decimal number [00,61].
    31     %z  Time zone offset from UTC.
    32     %a  Locale's abbreviated weekday name.
    33     %A  Locale's full weekday name.
    34     %b  Locale's abbreviated month name.
    35     %B  Locale's full month name.
    36     %c  Locale's appropriate date and time representation.
    37     %I  Hour (12-hour clock) as a decimal number [01,12].
    38     %p  Locale's equivalent of either AM or PM.
    39 """
     1 None
     2 返回元祖------------------------------------------------------
     3 time.struct_time(tm_year=2020, tm_mon=8, tm_mday=26, tm_hour=3, tm_min=41, tm_sec=13, tm_wday=2, tm_yday=239, tm_isdst=0)
     4 time.struct_time(tm_year=2020, tm_mon=8, tm_mday=26, tm_hour=11, tm_min=41, tm_sec=13, tm_wday=2, tm_yday=239, tm_isdst=0)
     5 time.struct_time(tm_year=2803, tm_mon=2, tm_mday=12, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=43, tm_isdst=-1)
     6 返回秒------------------------------------------------------
     7 -28800
     8 -32400
     9 返回时间戳------------------------------------------------------
    10 1598413273.624613
    11 1598413273.0
    12 返回格式化字符串------------------------------------------------------
    13 2020-08>>26
    14 Wed Aug 26 11:41:13 2020
    15 Wed Aug 26 11:41:13 2020

    2、datetime模块

     1 # Author:ZHJ
     2 import datetime
     3 
     4 print(datetime.datetime.now()) # 返回2020-08-26 11:46:14.354203
     5 print(datetime.datetime.now() + datetime.timedelta(3)) # 返回三天后时间2020-08-29 11:47:53.891897
     6 print(datetime.datetime.now() + datetime.timedelta(hours=3)) # 返回三小时后时间2020-08-26 14:48:56.034451
     7 print(datetime.datetime.now() + datetime.timedelta(minutes=30)) # 返回30分钟后时间2020-08-26 12:19:50.847586
     8 # 需要之前时间传递参数为负值
     9 
    10 
    11 # 时间替换,不是真的改系统时间
    12 print(datetime.datetime.now())
    13 c_time = datetime.datetime.now()
    14 print(c_time.replace(minute=30,hour=12))

    六、内置模块详解之Random模块

     自己取文件名一定要与导入的模块名区别开,如果相同会导致导入模块错误

     1 # Author:ZHJ
     2 import random
     3 
     4 # print(random.random())
     5 print(random.random())  # 0-1的随机浮点数
     6 print(random.randint(1, 5))  # 左闭右闭区间取随机整数
     7 print(random.randrange(1, 2))  # 左闭右开区间取随机整数,random.randrange([start], stop[, step])
     8 print(random.choice("asdfghjk1234567890"))  # 从序列中获取一个随机元素,list, tuple, 字符串都属于序列
     9 print(random.sample("asdfg34sdfw34", 5))  # 从序列中随机获取5个元素,作为一个片断返回
    10 print(random.uniform(1,2))  # 区间随机浮点数
    11 
    12 list_t = [1,2,3,5,5,15,12,5,1,25,12,]
    13 random.shuffle(list_t)  # 将列表的元素打乱
    14 print(list_t)
    1 验证码
    2 # Author:ZHJ
    3 import random
    4 code = ""
    5 for i in random.sample("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", 5):
    6     code += i
    7 print(code)

    七、内置模块详解之OS模块

     1 # Author:ZHJ
     2 import  os
     3 import time
     4 # print(os.getcwd())  # 获取当前工作目录,及当前python脚本目录路径
     5 # print(os.chdir("F:PythonProject"))  # 改变当前脚本的工作目录
     6 # print(os.curdir)  # 返回当前目录
     7 # os.makedirs("aa/bb/cc")  # 可生成多层递归目录,注意反斜杠
     8 # os.removedirs("aa/bb/cc")  # 若目录为空则删除,递归到上一层,若也为空则山,以此类推
     9 # os.mkdir("cc") # 生成单级目录
    10 # os.rmdir("cc")  # 删除单级目录,非空则不删除,报错
    11 # os.listdir("C:\") # 列出目录下的所有子目录和文件,包括隐藏文件,返回列表
    12 # os.remove("新建文本文档.txt")  # 删除指定文件
    13 # os.rename("456.txt","123.txt")  # 重命名文件
    14 # print(os.stat("F:PythonProjectDay5")) #获取文件或目录信息
    15 # print(os.sep)  # 输出操作系统路径分隔符
    16 # print(os.linesep)  # 输出操作系统行终止符
    17 # print(os.pathsep)  # 用于分割文件路径的字符串,就是环境 变量里分割路径的字符串
    18 # print(os.name)  # 指示当前使用平台
    19 # print(os.system("dir"))  # 指示当前使用平台,dos命令
    20 # print(os.environ)  # 获取系统环境变量
    21 # print(os.path.abspath(os.getcwd()))  # 返回path规范化的绝对路径
    22 print(os.path.split(os.getcwd()))  # 将path分割成目录和文件名元组返回
    23 print(os.path.dirname(os.getcwd()))  # 返回这个os.path.split返回元祖的第一个元素
    24 print(os.path.basename(os.getcwd()))  # 返回这个os.path.split返回元祖的第二个元素
    25 print(os.path.exists(os.getcwd()))  # 路径存在返回True,否则返回false
    26 print(os.path.isabs(os.getcwd()))  # 是否是绝对路径
    27 print(os.path.isfile(os.getcwd()))  # 路径是一个存在的文件返回True
    28 print(os.path.isdir(os.getcwd()))  # 是否是一个目录
    29 print(os.path.join(os.getcwd()),"/au")  # 多个路径组合后返回,第一个绝对路径前的参数将被忽略
    30 print(time.ctime(os.path.getatime(r"F:PythonProject123.txt")))  # 路径所指文件或目录的最后访问时间
    31 print(time.ctime(os.path.getmtime(r"F:PythonProject123.txt")))  # 路径所指文件或目录的最后修改时间
     1 import sys,os
     2 def run():
     3     print("sys.path[0]返回路径-----",sys.path[0])
     4     print("sys.argv[0]返回路径-----",sys.argv[0])
     5     print("os.getcwd()返回路径-----",os.getcwd())
     6     print("__file__返回路径-----",__file__)
     7     print("os.path.abspath('.')返回路径-----",os.path.abspath('.'))
     8     print("os.path.realpath('.')返回路径-----",os.path.realpath('.'))
     9 run()
    10 
    11 # 被调用时执行结果
    12 # sys.path[0]返回路径----- F:PythonProject路径测试
    13 # sys.argv[0]返回路径----- F:/Python/Project/路径测试/test.py
    14 # os.getcwd()返回路径----- F:PythonProject路径测试
    15 # __file__返回路径----- F:PythonProject路径测试adsss	.py
    16 # os.path.abspath('.')返回路径----- F:PythonProject路径测试
    17 # 自己执行结果
    18 # sys.path[0]返回路径----- F:PythonProject路径测试adsss
    19 # sys.argv[0]返回路径----- F:/Python/Project/路径测试/ad/sss/t.py
    20 # os.getcwd()返回路径----- F:PythonProject路径测试adsss
    21 # __file__返回路径----- F:/Python/Project/路径测试/ad/sss/t.py
    22 # os.path.abspath('.')返回路径----- F:PythonProject路径测试adsss

    根据上面的执行结果,可以看出使用__file__形式可以保证路径的一致性

    八、内置模块详解之Sys和shutil模块

     1、sys

     1 import sys
     2 x = sys.argv  # 接收命令行传递的参数
     3 print(x)
     4 
     5 x = sys.path  # 打印系统环境变量
     6 print(x)
     7 
     8 x = sys.version  # 获取解释器版本
     9 print(x)
    10 
    11 x = sys.platform  # 返回操作系统平台名称
    12 print(x)
    13 
    14 sys.stdout.write("输出的文本")  # print输出自动换行,这个不换行
    15 print("输出的文本")  #
    16 
    17 """
    18 sys.stdin.readline( )会将标准输入全部获取,包括末尾的'
    ',
    19 因此用len计算长度时是把换行符'
    '算进去了的,但是input( )获取输入时返回的结果是不包含末尾的换行符'
    '的。
    20 """
    21 print("请输入!")
    22 x = sys.stdin.readline()  # input()括号内可以直接填写说明文字,sys.stdin还需要加个print方法给出提示信息。
    23 print(x)
    24 x = input("请输入!")
    25 print(x)
    26 
    27 x = sys.stdin.readline( )[:-1]  # 去掉结尾换行

    2、shutil

      高级的文件、文件夹、压缩包处理模块

     1 import shutil
     2 """
     3 必须先打开文件才可以复制
     4 """
     5 # f1 = open("复制.txt", "r", encoding="utf-8")
     6 # f2 = open("复制_副本.txt", "w", encoding="utf-8")
     7 # shutil.copyfileobj(f1, f2, 20)
     8 
     9 """
    10 直接给文件名,就可以复制,源文件必须存在
    11 """
    12 # shutil.copyfile("复制.txt", "复制_副本.txt")
    13 
    14 """
    15 递归的拷贝目录和文件
    16 """
    17 # shutil.copytree("a", "aa")
    18 
    19 """
    20 递归的删除目录和文件
    21 """
    22 #shutil.rmtree("aa")
    23 
    24 """
    25 shutil.make_archive(base_name, format,...)
    26 base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
    27 如:www                        =>保存至当前路径
    28 如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
    29 format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
    30 root_dir: 要压缩的文件夹路径(默认当前目录)
    31 owner: 用户,默认当前用户
    32 group: 组,默认当前组
    33 logger: 用于记录日志,通常是logging.Logger对象
    34 """
    35 shutil.make_archive("ATM", "zip", "F:PythonProjectDay4") # 指定文件所在目录的所有文件打包

      shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的

     1 import zipfile
     2 
     3 # 压缩
     4 z = zipfile.ZipFile('laxi.zip', 'w')
     5 z.write('a.log')
     6 z.write('data.data')
     7 z.close()
     8 
     9 # 解压
    10 z = zipfile.ZipFile('laxi.zip', 'r')
    11 z.extractall()
    12 z.close()

    九、内置模块详解之Shelve模块

     shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式

    1 import shelve
    2 """
    3 shelve模块是一个简单的k,v将内存数据通过文件持久化的模块
    4 """
    5 d = shelve.open("test123")  # 文件可以不用存在
    6 # d["a"] = [123, 244, "hello"]
    7 # d.close()
    8 
    9 print(d.get("a"))  # 取回时使用get方法

    十、内置模块详解之Xml模块1

    遍历

     1 import xml.etree.ElementTree as ET
     2  
     3 tree = ET.parse("xmltest.xml")
     4 root = tree.getroot()
     5 print(root.tag)
     6  
     7 #遍历xml文档
     8 for child in root:
     9     print(child.tag, child.attrib)
    10     for i in child:
    11         print(i.tag,i.text)
    12  
    13 #只遍历year 节点
    14 for node in root.iter('year'):
    15     print(node.tag,node.text)

    十一、内置模块详解之Xml模块2

    修改和删除xml文档内容

     1 import xml.etree.ElementTree as ET
     2  
     3 tree = ET.parse("xmltest.xml")
     4 root = tree.getroot()
     5  
     6 #修改
     7 for node in root.iter('year'):
     8     new_year = int(node.text) + 1
     9     node.text = str(new_year)
    10     node.set("updated","yes")
    11  
    12 tree.write("xmltest.xml")
    13  
    14  
    15 #删除node
    16 for country in root.findall('country'):
    17    rank = int(country.find('rank').text)
    18    if rank > 50:
    19      root.remove(country)
    20  
    21 tree.write('output.xml')

    自己创建xml文档

     1 import xml.etree.ElementTree as ET
     2  
     3  
     4 new_xml = ET.Element("namelist")
     5 name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})
     6 age = ET.SubElement(name,"age",attrib={"checked":"no"})
     7 sex = ET.SubElement(name,"sex")
     8 sex.text = '33'
     9 name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})
    10 age = ET.SubElement(name2,"age")
    11 age.text = '19'
    12  
    13 et = ET.ElementTree(new_xml) #生成文档对象
    14 et.write("test.xml", encoding="utf-8",xml_declaration=True)
    15  
    16 ET.dump(new_xml) #打印生成的格式

    十二、内置模块详解之Configparser模块

    用于生成和修改常见配置文档,当前模块的名称在 python 3.x 版本中变更为 configparser。

    来看一个好多软件的常见文档格式如下

    [DEFAULT]
    ServerAliveInterval = 45
    Compression = yes
    CompressionLevel = 9
    ForwardX11 = yes
     
    [bitbucket.org]
    User = hg
     
    [topsecret.server.com]
    Port = 50022
    ForwardX11 = no

    如果想用python生成一个这样的文档怎么做呢?

     1 import configparser
     2  
     3 config = configparser.ConfigParser()
     4 config["DEFAULT"] = {'ServerAliveInterval': '45',
     5                       'Compression': 'yes',
     6                      'CompressionLevel': '9'}
     7  
     8 config['bitbucket.org'] = {}
     9 config['bitbucket.org']['User'] = 'hg'
    10 config['topsecret.server.com'] = {}
    11 topsecret = config['topsecret.server.com']
    12 topsecret['Host Port'] = '50022'     # mutates the parser
    13 topsecret['ForwardX11'] = 'no'  # same here
    14 config['DEFAULT']['ForwardX11'] = 'yes'
    15 with open('example.ini', 'w') as configfile:
    16    config.write(configfile)

    写完了还可以再读出来

     1 >>> import configparser
     2 >>> config = configparser.ConfigParser()
     3 >>> config.sections()
     4 []
     5 >>> config.read('example.ini')
     6 ['example.ini']
     7 >>> config.sections()
     8 ['bitbucket.org', 'topsecret.server.com']
     9 >>> 'bitbucket.org' in config
    10 True
    11 >>> 'bytebong.com' in config
    12 False
    13 >>> config['bitbucket.org']['User']
    14 'hg'
    15 >>> config['DEFAULT']['Compression']
    16 'yes'
    17 >>> topsecret = config['topsecret.server.com']
    18 >>> topsecret['ForwardX11']
    19 'no'
    20 >>> topsecret['Port']
    21 '50022'
    22 >>> for key in config['bitbucket.org']: print(key)
    23 ...
    24 user
    25 compressionlevel
    26 serveraliveinterval
    27 compression
    28 forwardx11
    29 >>> config['bitbucket.org']['ForwardX11']
    30 'yes'

    configparser增删改查语法

     1 [section1]
     2 k1 = v1
     3 k2:v2
     4   
     5 [section2]
     6 k1 = v1
     7  
     8 import ConfigParser
     9   
    10 config = ConfigParser.ConfigParser()
    11 config.read('i.cfg')
    12   
    13 # ########## 读 ##########
    14 #secs = config.sections()
    15 #print secs
    16 #options = config.options('group2')
    17 #print options
    18   
    19 #item_list = config.items('group2')
    20 #print item_list
    21   
    22 #val = config.get('group1','key')
    23 #val = config.getint('group1','key')
    24   
    25 # ########## 改写 ##########
    26 #sec = config.remove_section('group1')
    27 #config.write(open('i.cfg', "w"))
    28   
    29 #sec = config.has_section('wupeiqi')
    30 #sec = config.add_section('wupeiqi')
    31 #config.write(open('i.cfg', "w"))
    32   
    33   
    34 #config.set('group2','k1',11111)
    35 #config.write(open('i.cfg', "w"))
    36   
    37 #config.remove_option('group2','age')
    38 #config.write(open('i.cfg', "w"))

    十三、内置模块详解之Hashlib、Hmac模块

     用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

     1 import hashlib
     2  
     3 m = hashlib.md5()
     4 m.update(b"Hello")
     5 m.update(b"It's me")
     6 print(m.digest())
     7 m.update(b"It's been a long time since last time we ...")
     8  
     9 print(m.digest()) #2进制格式hash
    10 print(len(m.hexdigest())) #16进制格式hash
    11 '''
    12 def digest(self, *args, **kwargs): # real signature unknown
    13     """ Return the digest value as a string of binary data. """
    14     pass
    15  
    16 def hexdigest(self, *args, **kwargs): # real signature unknown
    17     """ Return the digest value as a string of hexadecimal digits. """
    18     pass
    19  
    20 '''
    21 import hashlib
    22  
    23 # ######## md5 ########
    24  
    25 hash = hashlib.md5()
    26 hash.update('admin')
    27 print(hash.hexdigest())
    28  
    29 # ######## sha1 ########
    30  
    31 hash = hashlib.sha1()
    32 hash.update('admin')
    33 print(hash.hexdigest())
    34  
    35 # ######## sha256 ########
    36  
    37 hash = hashlib.sha256()
    38 hash.update('admin')
    39 print(hash.hexdigest())
    40  
    41  
    42 # ######## sha384 ########
    43  
    44 hash = hashlib.sha384()
    45 hash.update('admin')
    46 print(hash.hexdigest())
    47  
    48 # ######## sha512 ########
    49  
    50 hash = hashlib.sha512()
    51 hash.update('admin')
    52 print(hash.hexdigest())

    散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。使用HMAC时,消息通讯的双方,通过验证消息中加入的鉴别密钥K来鉴别消息的真伪;

    一般用于网络通信中消息加密,前提是双方先要约定好key,就像接头暗号一样,然后消息发送把用key把消息加密,接收方用key + 消息明文再加密,拿加密后的值 跟 发送者的相对比是否相等,这样就能验证消息的真实性,及发送者的合法性了。

    1 import hmac
    2 h = hmac.new('中文'.encode(encoding="utf-8"), '中文怎么办'.encode(encoding="utf-8"))
    3 print h.hexdigest()

    十四、正则表达式Re模块使用详解

     用正则表达式符号

     1 '.'     默认匹配除
    之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
     2 '^'     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","
    abc
    eee",flags=re.MULTILINE)
     3 '$'     匹配字符结尾,或e.search("foo$","bfoo
    sdfsf",flags=re.MULTILINE).group()也可以
     4 '*'     匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为['abb', 'ab', 'a']
     5 '+'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
     6 '?'     匹配前一个字符1次或0次
     7 '{m}'   匹配前一个字符m次
     8 '{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
     9 '|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
    10 '(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c
    11  
    12  
    13 'A'    只从字符开头匹配,re.search("Aabc","alexabc") 是匹配不到的
    14 ''    匹配字符结尾,同$
    15 'd'    匹配数字0-9
    16 'D'    匹配非数字
    17 'w'    匹配[A-Za-z0-9]
    18 'W'    匹配非[A-Za-z0-9]
    19 's'     匹配空白字符、	、
    、
     , re.search("s+","ab	c1
    3").group() 结果 '	'
    20  
    21 '(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}

    最常用的匹配语法

    re.match 从头开始匹配
    re.search 匹配包含
    re.findall 把所有匹配到的字符放到以列表中的元素返回
    re.splitall 以匹配到的字符当做列表分隔符
    re.sub      匹配字符并替换

    反斜杠的困扰
    与大多数编程语言相同,正则表达式里使用""作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\"表示。同样,匹配一个数字的"\d"可以写成r"d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

     1 import re
     2 info = "abbb3cabb3abc6bbac"
     3 # x = re.match("ab*", info)  # 从头开始匹配,匹配一个
     4 # x = re.search("ab*", info)  # 整个字符串,找到匹配样式的第一个位置,并返回一个相应的 匹配对象
     5 # x = re.fullmatch("abbbcabb3abcbbac", info)  # 完全匹配,表达式和字符串完全一样
     6 # lt1 = re.split("d", info)  # 用正则表达式分开字符串,并返回列表
     7 # lt2 = re.findall("ab{0,2}", info)  # 匹配所有, string 从左到右进行扫描,匹配按找到的顺序返回
     8 # info = "heggfdello"
     9 # lt3 = re.findall("e.+e", info)
    10 # info = "576h"
    11 # x = re.search("A[0-9]+[a-z]$", info)
    12 # print(lt1)
    13 # print(lt2)
    14 # print(lt3)
    15 # if x:
    16 #     print(x.group())
    17 # else:
    18 #     print("没有匹配对象")
    19 
    20 #(?P<name>...)' 分组匹配 '
    21 # 分割身份证号码案例
    22 # x = re.search("(?P<province>[0-9]{2})(?P<city>[0-9]{2})(?P<county>[0-9]{2})(?P<birthday>[0-9]{8})(?P<ID>[0-9]{4})", "610121198711026734")
    23 # if x:
    24 #     print(x.groupdict())
    25 # else:
    26 #     print("没有匹配对象")
    27 
    28 x = re.sub("[0-9]","@","cjh378jj68ubdh9jhd3du8",count= 2)  # 将字符串中的数字替换成@符号,count替换几次
    29 print(x)

    作业:开发一个简单的python计算器

    1. 实现加减乘除及括号优先级解析
    2. 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果,结果必须与真实的计算器所得出的结果一致

      过程中遇到的麻烦:

    # int()函数里面不能传浮点数,但fload()函数里可以传整数

    # TypeError: 'str' object is not callable
    # 细看了一下代码,原来是之前将一个变量命名为 str,
    # 之后又把它作为底层 str() 进行调用。其实这时候,它已经不再是 Python 的底层函数咯。

    # 递归函数返回值为None 的问题,解决办法的思路就是:使每次递归都要能够执行到return语句 。

    # 不匹配两边括号的正则,只匹配括号里内容(?<=()[^()]+(?=))

      1 # Author:ZHJ
      2 import re
      3 #  int()函数里面不能传浮点数,但fload()函数里可以传整数
      4 
      5 #  TypeError: 'str' object is not callable
      6 #  细看了一下代码,原来是之前将一个变量命名为 str,
      7 #  之后又把它作为底层 str() 进行调用。其实这时候,它已经不再是 Python 的底层函数咯。
      8 
      9 #递归函数返回值为None 的问题,解决办法的思路就是:使每次递归都要能够执行到return语句 。
     10 
     11 # 不匹配两边括号的正则,只匹配括号里内容(?<=()[^()]+(?=))
     12 
     13 def calculate_dual(equation):
     14     """
     15     计算两个数值的加减乘除
     16     :param equation: 是一个字符串,例:3*4
     17     :return: 返回加减乘除的结果
     18     """
     19     if re.search("[0-9]+*(-?)[0-9]+",equation):  # 如果两个数相乘可以匹配到
     20         lt = re.split("*", equation)  # 以乘号分割
     21         return float(lt[0]) * float(lt[1])  #分隔后两个列表元素相乘返回
     22     elif re.search("(-?)[0-9]+/(-?)[0-9]+",equation):
     23         lt = re.split("/", equation)
     24         return float(lt[0]) / float(lt[1])
     25     elif re.search("(-?)[0-9]++(-?)[0-9]+",equation):
     26         lt = re.split("+", equation)
     27         return float(lt[0]) + float(lt[1])
     28     elif re.search("(-?)[0-9]+-(-?)[0-9]+",equation):
     29         lt = re.split("-", equation)
     30         return float(lt[0]) - float(lt[1])
     31 
     32 
     33 def cl_mul_and_div(equation):
     34     """
     35     计算一个算式中的乘除,用正则匹配第一个乘或除,计算后替换原来算式,递归后接着算,知道匹配不上乘除
     36     说明式子中只剩加减;
     37     递归函数中是用返回值,返回none,需要在每一次递归时要执行返回值,需要把递归那一句代码也加return
     38     :param equation:
     39     :return:
     40     """
     41     # print(equation)
     42     z = re.search("[0-9]*.?[0-9]+(*|/)(-?)[0-9]*.?[0-9]+",equation)
     43     if z:
     44         # print(z.group())
     45         t = re.sub(re.escape(z.group()), str(calculate_dual(z.group())),equation)
     46         # print(calculate_dual(z.group()))
     47         return cl_mul_and_div(t)
     48     else:
     49         # print("sss",equation)
     50         return equation
     51 
     52 
     53 def cl_add_and_sub(equation):
     54     """
     55     计算一个算式中的加减,用正则匹配第一个加或减,计算后替换原来算式,递归后接着算,知道匹配不上加减
     56     说明已经算出结果
     57     :param equation:
     58     :return:
     59     """
     60     # print(equation)
     61     z = re.search("(-?)[0-9]*.?[0-9]+(+|-)[0-9]*.?[0-9]+",equation)
     62     if z:
     63         # print(z.group())
     64         t = re.sub(re.escape(z.group()), str(calculate_dual(z.group())),equation)
     65         #print(t)
     66         return cl_add_and_sub(t)
     67     else:
     68         return equation
     69 
     70 
     71 def cl_inner_brackets(p):
     72     """
     73     计算在括号里的算式
     74     :param p:
     75     :return:
     76     """
     77     return cl_add_and_sub(cl_mul_and_div(p))
     78 def remove_brackets(s):
     79     """
     80     去掉两边的括号
     81     :param s:
     82     :return:
     83     """
     84     #print(s)
     85     return re.search("(?<=()[^()]+(?=))", s).group()
     86 def chu_li_fu_hao(s):
     87     """
     88     处理正负号
     89     :param s:
     90     :return:
     91     """
     92     # print("处理符号前",s)
     93     while True:
     94         a = re.search("(+-)", s)
     95         #print(a)
     96         b = re.search("(--)", s)
     97         if a:
     98             s = re.sub(re.escape(a.group()), "-", s)
     99             # print("处理符号后",s)
    100         elif b:
    101             s = re.sub(re.escape(b.group()), "+", s)
    102             # print("处理符号后", s)
    103         else:
    104             return s
    105 temp = "1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))"
    106 # temp = "(9-10+5)*3+3-98/(4+99)*3/3+(1*6)"
    107 def cl(temp):
    108     x = re.search("(()[^()]+())", temp)
    109 
    110     if x:
    111         # print("被替换的",x.group())
    112         # print("计算结果", remove_brackets(cl_inner_brackets(x.group())))
    113         t = re.sub(re.escape(x.group()),remove_brackets(cl_inner_brackets(x.group())),temp)
    114 
    115         t = chu_li_fu_hao(t)
    116         # print("ass",x)
    117         return cl(t)
    118     else:
    119         if re.search("[+-*/]", temp):
    120             # print(temp)
    121             w = chu_li_fu_hao(cl_inner_brackets(temp))
    122             return cl(w)
    123         else:
    124             return temp
    125 print("user->",cl(temp))
    126 print("eval->",eval(temp))

    Python 递归函数返回值为None的解决办法

     https://blog.csdn.net/ha_hha/article/details/79393041

    __file__
  • 相关阅读:
    redhat yum ISO 本地源
    md5sum的使用
    查看进程内存使用情况
    常见User-Agent大全
    aggregate和annotate使用
    Django logging配置
    Django 开发调试工具:Django-debug-toolbar
    浏览器的同源策略及跨域解决方案
    Python contenttypes组件
    Dajngo admin
  • 原文地址:https://www.cnblogs.com/zhao-jun/p/13558268.html
Copyright © 2011-2022 走看看