day5-python常用的几个模块和计算器作业

1. 模块:能够实现某个功能的一组python代码组合;有标准库模块,开源模块和自定义模块三种;

 包:带有__init__.py的文件夹;

2. 几种导入模块的方式和区别;

·import module:实际上跟定义变量一个意思,定义module;引用的时候需要使用module.func1的方式进行调用,如果有多个地方使用到,会有性能损耗;

·from module import func1:将func1的代码执行一遍;

`import包:将__init__.py文件执行一遍;

3. 常用模块功能介绍;

(1)sys/os模块;

os: This module provides a portable way of using operating system dependent functionality.
翻译:提供一种方便的使用操作系统函数的方法。

--常用方法:

os.remove()       #删除文件 
os.rename()       #重命名文件 
os.walk()       #生成目录树下的所有文件名 
os.chdir()       #改变目录 
os.mkdir/makedirs()     #创建目录/多层目录 
os.rmdir/removedirs     #删除目录/多层目录 
os.listdir()       #列出指定目录的文件 
os.getcwd()       #取得当前工作目录 
os.chmod()       #改变目录权限 
os.path.basename()     #去掉目录路径,返回文件名 
os.path.dirname()     #去掉文件名,返回目录路径 
os.path.join()      #将分离的各部分组合成一个路径名 
os.path.split()      #返回(dirname(),basename())元组 
os.path.splitext()     #返回filename,extension)元组 
os.path.getatime\ctime\mtime   #分别返回最近访问、创建、修改时间 
os.path.getsize()     #返回文件大小 
os.path.exists()      #是否存在 
os.path.isabs()      #是否为绝对路径 
os.path.isdir()      #是否为目录 
os.path.isfile()      #是否为文件

sys:This module provides access to some variables used or maintained by the interpreter and to functions that interact strongly with the interpreter.
翻译:提供访问由解释器使用或维护的变量和在与解释器交互使用到的函数。

--常用方法;与解释器进行交互;

sys.argv     #命令行参数List,第一个元素是程序本身路径 
sys.modules.keys()   #返回所有已经导入的模块列表 
sys.exc_info()    #获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息 
sys.exit(n)    #程序,正常退出时exit(0) 
sys.hexversion    #获取Python解释程序的版本值,16进制格式如:0x020403F0 
sys.version    #获取Python解释程序的版本信息 
sys.maxint     #最大的Int值 
sys.maxunicode    #最大的Unicode值 
sys.modules    #返回系统导入的模块字段,key是模块名,value是模块 
sys.path     #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 
sys.platform    #返回操作系统平台名称 
sys.stdout     #标准输出  
sys.stdin     #标准输入 
sys.stderr     #错误输出  
sys.exc_clear()   #用来清除当前线程所出现的当前的或最近的错误信息 
sys.exec_prefix   #返回平台独立的python文件安装的位置 
sys.byteorder    #本地字节规则的指示器,big-endian平台的值是'big',little-endian平台的值是'little' 
sys.copyright    #记录python版权相关的东西 
sys.api_version   #解释器的C的API版本 
sys.version_info   #获取Python解释器的版本信息 
sys.getwindowsversion  #获取Windows的版本
sys.getdefaultencoding  #返回当前你所用的默认的字符编码格式
sys.getfilesystemencoding #返回将Unicode文件名转换成系统文件名的编码的名字
sys.setdefaultencoding(name) #用来设置当前默认的字符编码
sys.builtin_module_names #Python解释器导入的模块列表 
sys.executable    #Python解释程序路径 
sys.stdin.readline   #从标准输入读一行,sys.stdout.write("a") 屏幕输出a

--举例使用:

import os,sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0,BASE_DIR)——指定插入的位置;
sys.path.append(BASE_DIR)

(2) time和datetime模块

·time有三种类型的时间模式:时间戳(time(),mktime(m)),字符串(strftime),class 'time.struct_time'(strptime,gmtime,localtime);

time_local = time.localtime()#time.struct_time(tm_year=2020, tm_mon=7, tm_mday=2, tm_hour=22, tm_min=18, tm_sec=49, tm_wday=3, tm_yday=184, tm_isdst=0)
print(time.mktime(time_local))#1593699529.0
print(time.strftime('%Y %m %d',time_local))#2020 07 02
print(time.asctime(time_local))#Thu Jul  2 22:18:49 2020
print(time.ctime(time.time())) #Thu Jul  2 22:18:49 2020

 `datetime,主要用于时间的前后计算;

print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天
print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天
print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时
print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分

(3) random模块,生成随机数;

print(random.random()) #生成0-1之间随机数
print(random.randint(1,10))#1-10之间正数,包括1和10
print(random.randrange(1,10))#1-10之间正数,包括1不包括10
#5位验证码;
import random
check_code = ''
for i in range(5):
    j = random.randrange(3)
    if i == j:
        tmp = chr(random.randint(65,90))
    else:
        tmp = random.randint(0, 9)
    if i == 3:
        tmp = random.randint(0,9)
    elif i == 4:
        tmp = chr(random.randint(65,90))
    check_code += str(tmp)

print(check_code)

(4)shutil模块参考:https://www.cnblogs.com/wupeiqi/articles/4963027.html

·shutil.copyfileobj(fsrc, fdst[, length]) 将文件内容拷贝到另一个文件中,lenth是一次拷贝的长度,这个命令需要手工打开文件;
·shutil.copyfile(src, dst) 拷贝文件
·shutil.copymode(src, dst) 仅拷贝权限。内容、组、用户均不变
·shutil.copystat(src, dst) 拷贝状态的信息,包括:mode bits, atime, mtime, flags
·shutil.copy(src, dst) 拷贝文件和权限
·shutil.copy2(src, dst) 拷贝文件和状态信息
·shutil.copytree(src, dst, symlinks=False, ignore=None) 递归的去拷贝文件
·shutil.rmtree(path[, ignore_errors[, onerror]]) 递归的去删除文件
·shutil.move(src, dst) 递归的去移动文件
·shutil.make_archive(base_name, format,...) 创建压缩包并返回文件路径,例如:zip、tar,shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,
* base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,如:www=>保存至当前路径如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
* format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
* root_dir: 要压缩的文件夹路径(默认当前目录)
* owner: 用户,默认当前用户
* group: 组,默认当前组
* logger: 用于记录日志,通常是logging.Logger对象

(5)json和pickle模块:用于序列化的两个模块

json,用于字符串 和 python数据类型间进行转换(比较简单的类型)
pickle,用于python特有的类型 和 python的数据类型间进行转换(所有python类型)
均提供了四个功能:dumps、dump、loads、load

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

import shelve
d = shelve.open('test7')

name = ['alex','roar']

def test_func():
    print('helll0')

test_dict = {'name':'alex','age':22}
print(test_func)


d['list'] = name
d['func'] = test_func
d['dict'] = test_dict
print(d.keys())
for i in d:
    print(i,d[i])
'''

list ['alex', 'roar']
func <function test_func at 0x7f912cd06550>
dict {'name': 'alex', 'age': 22}

'''

d.close()

(7)re模块:

'.'     默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
'^'     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$'     匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以
'*'     匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为['abb', 'ab', 'a']
'+'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
'?'     匹配前一个字符1次或0次
'{m}'   匹配前一个字符m次
'{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
'|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
'(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c
 
 
'\A'    只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的
'\Z'    匹配字符结尾,同$
'\d'    匹配数字0-9
'\D'    匹配非数字
'\w'    匹配[A-Za-z0-9]
'\W'    匹配非[A-Za-z0-9]
's'     匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
 
'(?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'}

(8) 计算器作业:

开发一个简单的python计算器

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

import re
def get_bra_pos(string):
    '''
    to get the position of brackets
    :param string:calculate string
    :return: [left_bra_pos,right_bar_pos]
    '''
    left_bra_list = []
    right_bra_list = []
    lr_bra_list = []
    for i,j in enumerate(string):
        if j == '(':
            left_bra_list.append(i)
        elif j == ')':
            right_bra_list.append(i)
        else:
            continue
    lr_bra_list.append(left_bra_list[-1])
    for x in right_bra_list:
        if x > left_bra_list[-1]:
            lr_bra_list.append(x)
            break
    return lr_bra_list


def one_type_operation_pos(string):
    '''
    return a position list of string with only one type operation like '+-' or '*/'
    :param string:
    :return: position list
    '''
    pos_list = []
    for i,j in enumerate(string):
        operation_flag = re.match('\D',j)
        if operation_flag:
            if j == '.':
                continue
            else:
                pos_list.append(i)
        else:
            continue
    if 0 in pos_list:
        pos_list.remove(0)
    return pos_list


def simple_cal(string):
    '''
    only handle expression with one operator
    :return:
    consider -1.9+8
    '''
    if string[0] == '-':
        string1 = string[1:]
        opeartor = re.findall("\D",string1)
    else:
        opeartor = re.findall("\D", string)
    if '.' in opeartor:
        opeartor.remove('.')
    ope_position = 0
    for i,j in enumerate(string):
        if i ==0 and j == '-':
            continue
        if j == opeartor[0]:
            ope_position = i
            break
        else:
            continue
    a = string[:ope_position]
    b = string[ope_position+1:]
    a = float(a)
    b = float(b)
    # print('simple_cal',a,b)
    if '+' in opeartor:
        return a+b
    elif '-' in opeartor:
        return a-b
    elif '*' in opeartor:
        return a*b
    elif '/' in opeartor:
        return a/b
    elif '#' in opeartor:
        return a*b*-1
    elif '@' in opeartor:
        return a/b*-1


def two_ope_nearby(string):
    if '+-' in string:
        string = string.replace('+-','-')
    elif '--' in string:
        string = string.replace('--','+')
    elif '*-' in string:
        string = string.replace('*-','#')
    elif '/-' in string:
        string = string.replace('/-','@')
    return string


def exp_onetype_operation(string):
    '''
    handle expression only plus and minus or only times and devide
    :return:expression calculate result
    mention exp like '1--2776671.6952380957'
    '''
    while True:
        string = two_ope_nearby(string)
        pos_list = one_type_operation_pos(string)
        if len(pos_list) == 1:
            result = simple_cal(string)
            break
        else:
            cal_str = string[:pos_list[1]]
            result = simple_cal(cal_str)
            string = str(result)+string[pos_list[1]:]
    return result


def exp_twotype_operation(string):
    '''
    handle expression with all operations
    :return:expression calculate result
    '''
    while True:
        pm_list = []
        td_list = []
        string = two_ope_nearby(string)
        for i, j in enumerate(string):
            if j == '-' or j == '+':
                pm_list.append(i)
            elif j == '*' or j == '/' or j == '#' or j == '@':
                td_list.append(i)
        if 0 in pm_list:
            pm_list.remove(0)
        if pm_list and td_list:
            if pm_list[0] < td_list[0]:
                if len(pm_list) == 1:
                    td_str = string[pm_list[0]+1:]
                    result = exp_onetype_operation(td_str)
                    string = string[:pm_list[0]+1]+str(result)
                else:
                    if pm_list[-1] < td_list[0]:
                        td_str = string[pm_list[-1] + 1:]
                        result = exp_onetype_operation(td_str)
                        string = string[:pm_list[-1] + 1] + str(result)
                    else:
                        pmtd_pos = 0
                        for k in td_list:
                            for j,l in enumerate(pm_list):
                                if l < k and pm_list[j+1] > k:
                                    pmtd_pos = j
                                    break
                            break
                        td_str = string[pm_list[pmtd_pos]+1:pm_list[pmtd_pos+1]]
                        result = exp_onetype_operation(td_str)
                        string = string[:pm_list[pmtd_pos] + 1] + str(result)+string[pm_list[pmtd_pos+1]:]
            else:
                td_str = string[:pm_list[0]]
                result = exp_twotype_operation(td_str)
                string = str(result)+string[pm_list[0]:]
        else:
            result = exp_onetype_operation(string)
            break
    return result


def exp_man(string):
    '''
    handle expression with pmtd as "1+3*7+8/3*6*2"
    :return: expression calculate result
    firstly,judge if <0;
    pm_list to record the exp in '+-'
    td_list to record the exp not in '+-'
    neg_flag need to mention as '-1388337.0476190478+12.0/10.0'
    '''
    pm_list = []
    td_list = []
    neg_flag = re.match('^-\d',string)
    for i,j in enumerate(string):
        if j == '-' or j == '+':
            pm_list.append(i)
        elif j == '*' or j == '/' or j == '#' or j == '@':
            td_list.append(i)
    if 0 in pm_list:
        pm_list.remove(0)
    if pm_list and td_list:
        result = exp_twotype_operation(string)
    else:
        result = exp_onetype_operation(string)
    return result


def exp_replace(ori_str,re_str,lr_bra_list):
    '''
    remove brackets
    :param ori_str: original string
    :param re_str:  string need to replace
    :return: the string has been replace
    :neg_flag firstly judge if the string has minus like (-10)
    '''
    re_str=str(re_str)
    neg_flag = re.search('-\d',re_str)
    t = lr_bra_list[0] - 1
    exp_beside_bra = ori_str[t]
    if neg_flag:
        if exp_beside_bra == '+':
            ori_str = ori_str[:t] + '-' + ori_str[t + 1:]
            re_str = re_str[1:]
        elif exp_beside_bra == '-':
            ori_str = ori_str[:t] + '+' + ori_str[t + 1:]
            re_str = re_str[1:]
        elif exp_beside_bra == '*':
            ori_str = ori_str[:t] + '#' + ori_str[t + 1:]
            re_str = re_str[1:]
        elif exp_beside_bra == '/':
            ori_str = ori_str[:t] + '@' + ori_str[t + 1:]
            re_str = re_str[1:]
    ori_str = ori_str[:t + 1] + re_str + ori_str[lr_bra_list[1] + 1:]
    return ori_str


def exp_managerment(string):
    '''
    the func to get original expression from main to calculate
    :param string:
    :return: result has been calculated
    '''
    while True:
        string = string.replace(" ", "")
        if '(' in string:
            lr_bra_list = get_bra_pos(string)
            re_str = string[lr_bra_list[0]+1:lr_bra_list[1]]
            re_str = exp_man(re_str)
            string = exp_replace(string, re_str, lr_bra_list)
        else:
            result = exp_man(string)
            return result

 

posted @ 2020-07-03 17:05  roarlion  阅读(238)  评论(0)    收藏  举报