python模块

一、模块介绍

1、什么是模块?
    模块就是一系列功能的集合体,分为三大类
        I:内置的模块
        II:第三方的模块
        III:自定义的模块
            一个python文件本身就一个模块,文件名m.py,模块名叫m

            ps:模块有四种形式
              1 使用python编写的.py文件

              2 已被编译为共享库或DLL的C或C++扩展
            
              3 把一系列模块组织到一起的文件夹

                   (注:文件夹下有一个__init__.py文件,该文件夹称之为包)
            
              4 使用C编写并链接到python解释器的内置模块
                        
2、为何有用模块
    I:内置与第三的模块拿来就用,无需定义,这种拿来主义,可以极大地提升自己的开发效率
    II:自定义的模块
        可以将程序的各部分功能提取出来放到一模块中为大家共享使用
        好处是减少了代码冗余,程序组织结构更加清晰
        

3、如何用模块
'''

y=333
z=444
import foo
# 1、首次导入模块会发生3件事
# 1、执行foo.py
# 2、产生foo.py的名称空间,将foo.py运行过程中产生的名字都丢到foo的名称空间中
# 3、在当前文件中产生的有一个名字foo,该名字指向2中产生的名称空间

# 之后的导入,都是直接引用首次导入产生的foo.py名称空间,不会重复执行代码
# import foo
# import foo
# import foo
# import foo


# 2、引用:
# print(foo.x)
# print(foo.get)
# print(foo.change)
# 强调1:模块名.名字,是指名道姓地问某一个模块要名字对应的值,不会与当前名称空间中的名字发生冲突
# x=1111111111111
# print(x)
# print(foo.x)

# 强调2:无论是查看还是修改操作的都是模块本身,与调用位置无关
# import foo
#
# x=3333333333
# # foo.get()
#
# foo.change()
# print(x)
#
# print(foo.x)
# foo.get()


# 3、可以以逗号为分隔符在一行导入多个模块
# 建议如下所示导入多个模块
# import time
# import foo
# import m

# 不建议在一行同时导入多个模块
import time,foo,m


# 4、导入模块的规范
#I. python内置模块
#II. 第三方模块
#III. 程序员自定义模块

# import time
# import sys
#
# import 第三方1
# import 第三方2
#
# import 自定义模块1
# import 自定义模块2
# import 自定义模块3


# 5、import 。。。 as 。。。
# import foo as f # f=foo
# f.get()


# import abcdefgadfadfas
# #
# # abcdefgadfadfas.f1
# # abcdefgadfadfas.f2
# # abcdefgadfadfas.f3


# import abcdefgadfadfas as mmm
#
# mmm.f1
# mmm.f2
# mmm.f3


#6、模块是第一类对象
import foo

#7、自定义模块的命名应该采用纯小写+下划线的风格


#8、可以在函数内导入模块
def func():
    import foo

二、一个py文件有几种用途

# 一个python文件有两种用途
# 1、被当成程序运行
# 2、被当做模块导入

# 二者的区别是什么?
 

三、from...import导入模块


# impot导入模块在使用时必须加前缀"模块."
# 优点:肯定不会与当前名称空间中的名字冲突
# 缺点:加前缀显得麻烦

# from ... import ...导入也发生了三件事
# 1、产一个模块的名称空间
# 2、运行foo.py将运行过程中产生的名字都丢到模块的名称空间去
# 3、在当前名称空间拿到一个名字,该名字与模块名称空间中的某一个内存地址
# from foo import x # x=模块foo中值0的内存地址
# from foo import get
# from foo import change

# print(x)
# print(get)
# print(change)
# x=333333333
# print(x)
# get()
# change()
# get()

# print(x)
# from foo import x # x=新地址
# print(x)

# from...impot...导入模块在使用时不用加前缀
# 优点:代码更精简
# 缺点:容易与当前名称空间混淆
# from foo import x # x=模块foo中值1的内存地址
# x=1111


# 一行导入多个名字(不推荐)
# from foo import x,get,change

# *:导入模块中的所有名字
# name='egon'
# from foo import *
# print(name)

from socket import *


# 了解:__all__
# from foo import *
# print(x)
# print(get)
# print(change)


# 起别名
from foo import get as g
print(g)


 

四、模块的搜索路径优先级

# 无论是import还是from...import在导入模块时都涉及到查找问题
# 优先级:
# 1、内存(内置模块)
# 2、硬盘:按照sys.path中存放的文件的顺序依次查找要导入的模块

# import sys
# 值为一个列表,存放了一系列的对文件夹
# 其中第一个文件夹是当前执行文件所在的文件夹
# print(sys.path)

# import foo # 内存中已经有foo了
# foo.say()
#
# import time
# time.sleep(10)
#
# import foo
# foo.say()


# 了解:sys.modules查看已经加载到内存中的模块
import sys
# import foo # foo=模块的内存地址
# del foo

# def func():
#     import foo # foo=模块的内存地址
#
# func()
#
# # print('foo' in sys.modules)
# print(sys.modules)


import sys
# 找foo.py就把foo.py的文件夹添加到环境变量中
sys.path.append(r'/Users/linhaifeng/PycharmProjects/s14/day21/aa')
# import foo
# foo.say()

from foo import say

五、函数的类型提示

#            str  int   ('play','music')
# def register(name:str,age:int,hobbbies:tuple)->int:
#  print(name)
#  print(age)
#  print(hobbbies)
#  return 111
#
# # register(1,'aaa',[1,])
# res=register('egon',18,('play','music'))

# def register(name:str='egon',age:int=18,hobbbies:tuple=(1,2))->int:
#  print(name)
#  print(age)
#  print(hobbbies)
#  return 111
#
# # register(1,'aaa',[1,])
# # res=register('egon',18,('play','music'))
# res=register()


def register(name:"必须传入名字傻叉",age:1111111,hobbbies:"必须传入爱好元组")->"返回的是整型":
 print(name)
 print(age)
 print(hobbbies)
 return 111

# register(1,'aaa',[1,])
# res=register('egon',18,('play','music'))
# res=register('egon',19,(1,2,3))

print(register.__annotations__)

六、包的使用

'''
1、包就是一个包含有__init__.py文件的文件夹
    
    
2、为何要有包
    包的本质是模块的模块的一种形式,包是用来被当做模块导入
'''

#1、产生一个名称空间
#2、运行包下的__init__.py文件,将运行过程中产生的名字都丢到1的名称空间中
#3、在当前执行文件的名称空间中拿到一个名字mmm,mmm指向1的名称空间
# import mmm
# print(mmm.x)
# print(mmm.y)
# mmm.say()

# from mmm import x


# 模块的使用者:egon老湿

# 环境变量是以执行文件为准备的,所有的被导入的模块或者说后续的其他文件引用
# 的sys.path都是参照执行文件的sys.path
import sys
sys.path.append('/aaaaaaaaaaaaaaaaaaaaaaaaaa')
# print(sys.path)

sys.path.append(r'/Users/linhaifeng/PycharmProjects/s14/day21/aa')


# import foo # foo下__init__.py
# #
# #
# foo.f1()
# foo.f2()
# foo.f3()

# from foo import f1,f2,f3,f4

# f1()
# f2()
# f3()
# f4()

# import foo
# foo.f4()

# 强调:
# 1.关于包相关的导入语句也分为import和from ... import ...
# 两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:
# 凡是在导入时带点的,点的左边都必须是一个包,否则非法。
# 可以带有一连串的点,如import 顶级包.子包.子模块,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。
# 例如:
# from a.b.c.d.e.f import xxx
# import a.b.c.d.e.f
# 其中a、b、c、d、e 都必须是包


# 2、包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间
#
# 3、import导入文件时,产生名称空间中的名字来源于文件,
# import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件


# import foo
# # print(foo.f1)
# # print(foo.f2)
# # print(foo.f3)
# # print(foo.f4)
#
# foo.f4()

# from foo import *
# print(f1)
# print(f2)
# print(f3)
# print(f4)

七、时间模块

# 时间模块优先掌握的操作
#一:time
import time

# 时间分为三种格式:
# 1、时间戳:从1970年到现在经过的秒数
#    作用:用于时间间隔的计算

# print(time.time())

# 2、按照某种格式显示的时间:2020-03-30 11:11:11
#    作用:用于展示时间

# print(time.strftime('%Y-%m-%d %H:%M:%S %p'))
# print(time.strftime('%Y-%m-%d %X'))

# 3、结构化的时间
#    作用:用于单独获取时间的某一部分

# res=time.localtime()
# print(res)
# print(res.tm_year)
# print(res.tm_yday)

#二:datetime
import datetime

# print(datetime.datetime.now())
# print(datetime.datetime.now() + datetime.timedelta(days=3))
# print(datetime.datetime.now() + datetime.timedelta(weeks=1))

# 时间模块需要掌握的操作
# 1、时间格式的转换
# struct_time->时间戳
import time
# s_time=time.localtime()
# print(time.mktime(s_time))

# 时间戳->struct_time
# tp_time=time.time()
# print(time.localtime(tp_time))

# 补充:世界标准时间与本地时间
# print(time.localtime())
# print(time.gmtime()) # 世界标准时间,了解
# print(time.localtime(333333333))
# print(time.gmtime(333333333))


# struct_time->格式化的字符串形式的时间
# s_time=time.localtime()
# print(time.strftime('%Y-%m-%d %H:%M:%S',s_time))

# print(time.strptime('1988-03-03 11:11:11','%Y-%m-%d %H:%M:%S'))


# !!!真正需要掌握的只有一条:format string<------>timestamp
# '1988-03-03 11:11:11'+7

# format string--->struct_time--->timestamp
# struct_time=time.strptime('1988-03-03 11:11:11','%Y-%m-%d %H:%M:%S')
# timestamp=time.mktime(struct_time)+7*86400
# print(timestamp)

# format string<---struct_time<---timestamp
# res=time.strftime('%Y-%m-%d %X',time.localtime(timestamp))
# print(res)

# time.sleep(3)

# 了解知识
# import time
# print(time.asctime())


import datetime
# print(datetime.datetime.now())
# print(datetime.datetime.utcnow())

print(datetime.datetime.fromtimestamp(333333))
 

八、random模块


import random

# print(random.random()) #(0,1)----float    大于0且小于1之间的小数
# print(random.randint(1, 3))  # [1,3]    大于等于1且小于等于3之间的整数

# print(random.randrange(1, 3))  # [1,3)    大于等于1且小于3之间的整数
#
# print(random.choice([111, 'aaa', [4, 5]]))  # 1或者23或者[4,5]
#
# print(random.sample([111, 'aaa', 'ccc','ddd'],2))  # 列表元素任意2个组合
#
# print(random.uniform(1, 3))  # 大于1小于3的小数,如1.927109612082716
#
# item = [1, 3, 5, 7, 9]
# random.shuffle(item)  # 打乱item的顺序,相当于"洗牌"
# print(item)

# 应用:随机验证码

# import random
#
# res=''
# for i in range(6):
#     从26大写字母中随机取出一个=chr(random.randint(65,90))
#     从10个数字中随机取出一个=str(random.randint(0,9))
#
#     随机字符=random.choice([从26大写字母中随机取出一个,从10个数字中随机取出一个])
#     res+=随机字符


import random

def make_code(size=4):
    res=''
    for i in range(size):
        s1=chr(random.randint(65,90))
        s2=str(random.randint(0,9))
        res+=random.choice([s1,s2])
    return res

print(make_code(6))

九、OS模块

import os

# 获取某一个文件夹下所有的子文件以及子文件夹的名字
# res=os.listdir('.')
# print(res)
#
#
# size=os.path.getsize(r'/Users/linhaifeng/PycharmProjects/s14/day22/01 时间模块.py')
# print(size)

# os.remove()  删除一个文件
# os.rename("oldname","newname")  重命名文件/目录

# 应用程序----》"ls /"
# os.system("ls /")

# 规定:key与value必须都为字符串

# os.environ['aaaaaaaaaa']='111'
# print(os.environ)


# print(os.path.dirname(r'/a/b/c/d.txt'))
# print(os.path.basename(r'/a/b/c/d.txt'))


# print(os.path.isfile(r'笔记.txt'))
# print(os.path.isfile(r'aaa'))
# print(os.path.isdir(r'aaa'))

# print(os.path.join('a','/','b','c','d'))


# 推荐用这种
BASE_DIR=os.path.dirname(os.path.dirname(__file__))
# print(BASE_DIR)


# BASE_DIR=os.path.normpath(os.path.join(
#     __file__,
#     '..',
#     '..'
# ))
# print(BASE_DIR)

# 在python3.5之后,推出了一个新的模块pathlib
from pathlib import Path

# res = Path(__file__).parent.parent
# print(res)


# res=Path('/a/b/c') / 'd/e.txt'
# print(res)

# print(res.resolve())

10、sys模块

sys模块的常见函数列表
sys.argv: 实现从程序外部向程序传递参数。

sys.exit([arg]): 程序中间的退出,arg=0为正常退出。

sys.getdefaultencoding(): 获取系统当前编码,一般默认为ascii。

sys.setdefaultencoding(): 设置系统默认编码,执行dir(sys)时不会看到这个方法,在解释器中执行不通过,可以先执行reload(sys),在执行 setdefaultencoding('utf8'),此时将系统默认编码设置为utf8。(见设置系统默认编码 )

sys.getfilesystemencoding(): 获取文件系统使用编码方式,Windows下返回'mbcs',mac下返回'utf-8'.

sys.path: 获取指定模块搜索路径的字符串集合,可以将写好的模块放在得到的某个路径下,就可以在程序中import时正确找到。

sys.platform: 获取当前系统平台。

sys.stdin,sys.stdout,sys.stderr: stdin , stdout , 以及stderr 变量包含与标准I/O 流对应的流对象. 如果需要更好地控制输出,而print 不能满足你的要求, 它们就是你所需要的. 你也可以替换它们, 这时候你就可以重定向输出和输入到其它设备( device ), 或者以非标准的方式处理它们

 十一、 shutil模块


# 1、什么是序列化&反序列化
#   内存中的数据类型---->序列化---->特定的格式(json格式或者pickle格式)
#   内存中的数据类型<----反序列化<----特定的格式(json格式或者pickle格式)

#   土办法:
#   {'aaa':111}--->序列化str({'aaa':111})----->"{'aaa':111}"
#   {'aaa':111}<---反序列化eval("{'aaa':111}")<-----"{'aaa':111}"

# 2、为何要序列化
#   序列化得到结果=>特定的格式的内容有两种用途
#   1、可用于存储=》用于存档
#   2、传输给其他平台使用=》跨平台数据交互
#        python                 java
#         列表     特定的格式      数组

#   强调:
#       针对用途1的特定一格式:可是一种专用的格式=》pickle只有python可以识别
#       针对用途2的特定一格式:应该是一种通用、能够被所有语言识别的格式=》json


# 3、如何序列化与反序列化
# 示范1
# import json
# # 序列化
# json_res=json.dumps([1,'aaa',True,False])
# # print(json_res,type(json_res)) # "[1, "aaa", true, false]"
#
# # 反序列化
# l=json.loads(json_res)
# print(l,type(l))


# 示范2:
import json

# 序列化的结果写入文件的复杂方法
# json_res=json.dumps([1,'aaa',True,False])
# # print(json_res,type(json_res)) # "[1, "aaa", true, false]"
# with open('test.json',mode='wt',encoding='utf-8') as f:
#     f.write(json_res)

# 将序列化的结果写入文件的简单方法
# with open('test.json',mode='wt',encoding='utf-8') as f:
#     json.dump([1,'aaa',True,False],f)


# 从文件读取json格式的字符串进行反序列化操作的复杂方法
# with open('test.json',mode='rt',encoding='utf-8') as f:
#     json_res=f.read()
#     l=json.loads(json_res)
#     print(l,type(l))

# 从文件读取json格式的字符串进行反序列化操作的简单方法
# with open('test.json',mode='rt',encoding='utf-8') as f:
#     l=json.load(f)
#     print(l,type(l))


# json验证: json格式兼容的是所有语言通用的数据类型,不能识别某一语言的所独有的类型
# json.dumps({1,2,3,4,5})

# json强调:一定要搞清楚json格式,不要与python混淆
# l=json.loads('[1, "aaa", true, false]')
# l=json.loads("[1,1.3,true,'aaa', true, false]")
# print(l[0])

# 了解
# l = json.loads(b'[1, "aaa", true, false]')
# print(l, type(l))

# with open('test.json',mode='rb') as f:
#     l=json.load(f)


# res=json.dumps({'name':'哈哈哈'})
# print(res,type(res))

# res=json.loads('{"name": "\u54c8\u54c8\u54c8"}')
# print(res,type(res))

# 4、猴子补丁
# 在入口处打猴子补丁
# import json
# import ujson
#
# def monkey_patch_json():
#     json.__name__ = 'ujson'
#     json.dumps = ujson.dumps
#     json.loads = ujson.loads
#
# monkey_patch_json() # 在入口文件出运行


# import ujson as json # 不行

# 后续代码中的应用
# json.dumps()
# json.dumps()
# json.dumps()
# json.dumps()
# json.dumps()
# json.dumps()
# json.dumps()
# json.dumps()
# json.loads()
# json.loads()
# json.loads()
# json.loads()
# json.loads()
# json.loads()
# json.loads()
# json.loads()
# json.loads()
# json.loads()
# json.loads()

# 5.pickle模块
import pickle
# res=pickle.dumps({1,2,3,4,5})
# print(res,type(res))

# s=pickle.loads(res)
# print(s,type(s))


 


 十二、json&pickle模块

import configparser

config=configparser.ConfigParser()
config.read('test.ini')

# 1、获取sections
# print(config.sections())

# 2、获取某一section下的所有options
# print(config.options('section1'))

# 3、获取items
# print(config.items('section1'))

# 4、
# res=config.get('section1','user')
# print(res,type(res))

# res=config.getint('section1','age')
# print(res,type(res))


# res=config.getboolean('section1','is_admin')
# print(res,type(res))


# res=config.getfloat('section1','salary')
# print(res,type(res))
 

 十三、shelve模块


 十四、xml模块


 十五、configparser模块


 十六、hashlib模块

# 1、什么是哈希hash
#    hash一类算法,该算法接受传入的内容,经过运算得到一串hash值
#    hash值的特点:
#I 只要传入的内容一样,得到的hash值必然一样
#II 不能由hash值返解成内容
#III 不管传入的内容有多大,只要使用的hash算法不变,得到的hash值长度是一定

# 2、hash的用途
# 用途1:特点II用于密码密文传输与验证
# 用途2:特点I、III用于文件完整性校验

# 3、如何用
# import hashlib
#
# m=hashlib.md5()
# m.update('hello'.encode('utf-8'))
# m.update('world'.encode('utf-8'))
# res=m.hexdigest() # 'helloworld'
# print(res)
#
# m1=hashlib.md5('he'.encode('utf-8'))
# m1.update('llo'.encode('utf-8'))
# m1.update('w'.encode('utf-8'))
# m1.update('orld'.encode('utf-8'))
# res=m1.hexdigest()# 'helloworld'
# print(res)

# 模拟撞库
# cryptograph='aee949757a2e698417463d47acac93df'
# import hashlib
#
# # 制作密码字段
# passwds=[
#     'alex3714',
#     'alex1313',
#     'alex94139413',
#     'alex123456',
#     '123456alex',
#     'a123lex',
# ]
#
# dic={}
# for p in passwds:
#     res=hashlib.md5(p.encode('utf-8'))
#     dic[p]=res.hexdigest()
#
# # 模拟撞库得到密码
# for k,v in dic.items():
#     if v == cryptograph:
#         print('撞库成功,明文密码是:%s' %k)
#         break


# 提升撞库的成本=>密码加盐
import hashlib

m=hashlib.md5()

m.update('天王'.encode('utf-8'))
m.update('alex3714'.encode('utf-8'))
m.update('盖地虎'.encode('utf-8'))
print(m.hexdigest())

# m.update(文件所有的内容)
# m.hexdigest()
#
# f=open('a.txt',mode='rb')
# f.seek()
# f.read(2000) # 巨琳
# m1.update(文见的一行)
#
# m1.hexdigest()

 十七、suprocess模块

import subprocess

obj=subprocess.Popen('echo 123 ; ls / ; ls /root',shell=True,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 )

# print(obj)
# res=obj.stdout.read()
# print(res.decode('utf-8'))

err_res=obj.stderr.read()
print(err_res.decode('utf-8'))

 十八、 logging模块

import logging

logging.basicConfig(
    # 1、日志输出位置:1、终端 2、文件
    filename='access.log', # 不指定,默认打印到终端

    # 2、日志格式
    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',

    # 3、时间格式
    datefmt='%Y-%m-%d %H:%M:%S %p',

    # 4、日志级别
    # critical => 50
    # error => 40
    # warning => 30
    # info => 20
    # debug => 10
    level=10,
)

logging.debug('调试debug') # 10
logging.info('消息info')   # 20
logging.warning('警告warn')# 30
logging.error('egon提现失败') # 40
logging.critical('严重critical') # 50

十九、re模块

import re

print(re.findall('\w','aAbc123_*()-='))
print(re.findall('\W','aAbc123_*()-= '))
print(re.findall('\s','aA\rbc\t\n12\f3_*()-= '))
print(re.findall('\S','aA\rbc\t\n12\f3_*()-= '))
print(re.findall('\d','aA\rbc\t\n12\f3_*()-= '))
print(re.findall('\D','aA\rbc\t\n12\f3_*()-= '))
print(re.findall('\D','aA\rbc\t\n12\f3_*()-= '))
print(re.findall('\Aalex',' alexis alex sb'))
#                          alex
# print(re.findall('sb\Z',' alexis alexsb sb'))
#                                       sb\Z
print(re.findall('sb\Z',"""alex
alexis
alex
sb
"""))

# print(re.findall('^alex','alexis alex sb'))
# print(re.findall('sb$','alexis alex sb'))
# print(re.findall('sb$',"""alex
# alexis
# alex
# sb
# """))

# print(re.findall('^alex$','alexis alex sb'))
# print(re.findall('^alex$','al       ex'))
# print(re.findall('^alex$','alex'))

# 重复匹配:| . | * | ? | .* | .*? | + | {n,m} |
# 1、.:匹配除了\n之外任意一个字符,指定re.DOTALL之后才能匹配换行符
# print(re.findall('a.b','a1b a2b a b abbbb a\nb a\tb a*b'))
#                                                   a.b
# ['a1b','a2b','a b','abb','a\tb','a*b']
# print(re.findall('a.b','a1b a2b a b abbbb a\nb a\tb a*b',re.DOTALL))

# 2、*:左侧字符重复0次或无穷次,性格贪婪
# print(re.findall('ab*','a ab abb abbbbbbbb bbbbbbbb'))
#                                                ab*
#['a','ab','abb','abbbbbbbb']

# 3、+:左侧字符重复1次或无穷次,性格贪婪
# print(re.findall('ab+','a ab abb abbbbbbbb bbbbbbbb'))
#                         ab+

# 4、?:左侧字符重复0次或1次,性格贪婪
# print(re.findall('ab?','a ab abb abbbbbbbb bbbbbbbb'))
#                                                ab?
# ['a','ab','ab','ab']

# 5、{n,m}:左侧字符重复n次到m次,性格贪婪
# {0,} => *
# {1,} => +
# {0,1} => ?
# {n}单独一个n代表只出现n次,多一次不行少一次也不行

# print(re.findall('ab{2,5}','a ab abb abbb abbbb abbbbbbbb bbbbbbbb'))
#                                                           ab{2,5}
# ['abb','abbb','abbbb','abbbbb]

# print(re.findall('\d+\.?\d*',"asdfasdf123as1111111.123dfa12adsf1asdf3"))
#                                                                   \d+\.?\d*                                      \d+\.?\d+


# []匹配指定字符一个
# print(re.findall('a\db','a1111111b a3b a4b a9b aXb a b a\nb',re.DOTALL))
# print(re.findall('a[501234]b','a1111111b a3b a4b a9b aXb a b a\nb',re.DOTALL))
# print(re.findall('a[0-5]b','a1111111b a3b a1b a0b a4b a9b aXb a b a\nb',re.DOTALL))
# print(re.findall('a[0-9a-zA-Z]b','a1111111b axb a3b a1b a0b a4b a9b aXb a b a\nb',re.DOTALL))
#
# print(re.findall('a[^0-9a-zA-Z]b','a1111111b axb a3b a1b a0b a4b a9b aXb a b a\nb',re.DOTALL))
# print(re.findall('a-b','a-b aXb a b a\nb',re.DOTALL))
print(re.findall('a[-0-9\n]b','a-b a0b a1b a8b aXb a b a\nb',re.DOTALL))
 

二十、类型提示 Type hinting

类型提示 Type hinting


最低 Python 版本为 3.5
    from pathlib import Path
    root=Path(__file__)
    res=root.parent.parent / r'\bbb\aaa\ccc'
    print(res)

    print(res.resolve())

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

福海鑫森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值