zoukankan      html  css  js  c++  java
  • 模块

    本文讨论Python中模块的概念,全文分为两部分,第一部分介绍自定义模块的导入,第二部分介绍python中常见的内置模块。

    一:自定义模块

    1.模块的概念

      模块即一个py文件,在实际开发中,一个项目会分为很多的py文件,一个py文件就是一个模块

         模块的好处:

      模块的最大好处就是大大提高了代码的可维护性,其次,编写代码不必从零开始。当一个模块编写完毕,就可以在其他地方引用该模块,另外,使用模块还可以避免函数名和变量名冲突的情形。

      模块一共有三种:

      python标准库

      第三方模块

      自定义模块

    2.模块的导入方式:

    1 import cal  #导入cal.py
    2 from  cal import add    #从cal.py中导入add函数
    3 from cal import *   #不推荐使用
    4 res=add(4,5)
    5 print(res)

    上面三种方式都可以导入一个模块,但是建议使用前两种,不要使用最后一种,因为最后一种导入方式代码的可读性非常差。

     将module1中的test模块导入module模块中bin中的方法

    二.常见的内置模块:

    1.time模块:

     1 import time
     2 
     3 #-----------时间戳
     4 
     5 res=time.time() #返回1970年到现在,已经过去了多少秒钟,这个方法一般用来计算时间
     6 
     7 #-----------结构化时间(时间戳转化为结构化时间)
     8 
     9 res=time.localtime()    #以结构化的方式返回当前时间的年月日时分秒等信息
    10 t=time.localtime(122334243)   #可以传入一个参数,用来计算某一秒表示的年月日时分秒信息
    11 print(t.tm_year)    #输出结构化时间中的变量,tm_year表示年份
    12 
    13 #-------------结构化时间,UTC
    14 
    15 res=time.gmtime(123332)#用法与localtime一致,不过是返回标准时区(英国)的结构化时间
    16 
    17 
    18 #------------将结构化时间转化为时间戳
    19 
    20 res=time.mktime(time.localtime()) #mktime将结构化时间转为时间戳
    21 
    22 
    23 #------------将结构化时间转化为字符串时间 strftime
    24 res=time.strftime('%Y-%m-%d %X',time.localtime())#第一个参数是需要转化为字符串时间的格式,第二个参数是结构化时间
    25 
    26 #------------将字符串时间转化为结构化时间strptime
    27 res=time.strptime('2018:2:2 18:46:34','%Y:%m:%d %X')#第一个参数是·字符串时间,第二个参数是字符串时间的格式
    28 
    29 #-----------用固定的格式将结构化时间转为字符串时间
    30 
    31 res=time.ctime()    #将结构化时间转化为固定格式的字符串时间
    32 res=time.asctime()#将时间戳转为固定格式的字符串时间
    33 
    34 #-----------让进程睡眠一段时间
    35 time.sleep(1)
    36 
    37 import datetime
    38 
    39 res=datetime.datetime.now()#固定格式返回当前时间

    2.random模块

     1 import random
     2 
     3 res=random.random() #返回一个0-1之间的浮点型随机数
     4 
     5 res=random.randint(1,3) #返回一个1,3之间的整型随机数(包括3)
     6 
     7 res=random.randrange(1,3) #返回1-3之间的整型随机数(不包括3)
     8 
     9 res=random.choice([12,43,54,543,23443,42])  #从列表中随机选择一个元素
    10 
    11 res=random.sample([1,2,3,4,5,6,7,8],3)  #从列表中随机返回3个元素,返回结果以列表形式展现
    12 
    13 res=random.uniform(1,2) #返回1,2之间的一个随机浮点数
    14 
    15 ret=[1,2,3,4]
    16 random.shuffle(ret)     #打乱列表ret中元素的次序
    17 
    18 #简单的验证码
    19 def v_code():
    20     ret=''
    21     for i in range(5):
    22         num=random.randint(0,9)
    23         alum=chr(random.randint(65,122))  #chr将序号转为ACSII码中对应的字符
    24         s=str(random.choice([num,alum]))
    25         ret+=s
    26 
    27     return ret
    28 
    29 
    30 # print(ord('A')) #ord函数输出ascII编码中的字符的序号
    31 print(ord('z'))
    32 res=v_code()
    33 print(res)

    3.os模块

     1 import os
     2 
     3 res=os.getcwd() #获取当前工作目录,即当前python脚本工作的目录(不包含脚本本身)
     4 
     5 #os.chdir('dirname') #改变当前脚本工作目录,相当于shell下的cd命令
     6 
     7 os.curdir          #返回当前目录:('.')
     8 
     9 res=os.pardir      #获取当前目录的父目录字符串名('..')
    10 
    11 #os.makedirs('dirname1/dirname2') #生成多层递归目录
    12 
    13 #os.removedirs('dirname1/dirname2')#若目录为空,则删除,并递归到上一级目录,若也为空,则删除,以此类推,直到某一层目录不为空
    14 
    15 #os.mkdir('dirname1') #生成单及目录,相当于shell中mkdir命令
    16 
    17 #os.rmdir('dirname')  #删除单及目录,若目录不为空则无法删除,相当于shell中rmdir
    18 
    19 res=os.listdir('.') #列出指定目录下的所有文件和子目录
    20 
    21 #os.remove('bin.py')  #删除一个文件,慎用
    22 
    23 #os.rename('oldname','newname') #重命名文件/目录
    24 
    25 res=os.stat('dirname') #获取文件/目录信息,返回值中,st_atime代表最近一次查看的时间,st_mtime表示最近修改的时间,st_ctime表示创建的时间
    26 
    27 res=os.sep  #输出操作系统特定的路肩分隔符,windows下为或者\,linxu下为/
    28 
    29 res=os.linesep  #输出当前平台使用的行终止符,win下为	
    ,linux下
    
    30 
    31 res=os.pathsep  #输出用于分隔文件路径的字符串,win下wei;,linxu为:
    32 
    33 res=os.name #输出字符串指示当前使用平台,win->nt,linxu->posix
    34 
    35 #os.system('bash command') #运行shell命令,直接显示
    36 
    37 res=os.environ  #获取系统的环境变量
    38 
    39 #res=os.path.abspath(path) #返回path规范化的绝对路径
    40 
    41 #res=os.path.split(path)#将path分隔成目录和文件名的二元组返回
    42 
    43 #os.path.dirname(path) #返回path目录,其实就是os.path.split(path)的第一个元素
    44 
    45 #os.path.basename(path) #返回path的最后的文件名。如果path以/或结尾,那么就返回空,即os.path.split(path)的第二个元素
    46 
    47 os.path.exists(path)#如果path存在,返回true,否则返回false
    48 
    49 os.path.isabs(path) #如果path是绝对路径,返回true
    50 
    51 os.path.isfile(path)#如果path是一个存在的文件,则返回true
    52 
    53 os.path.isdir(path) #如果path是一个存在的目录,则返回true
    54 
    55 a='E:Projectpython'
    56 b='day3moduledirname'
    57 os.path.join(a,b)#a,b路径拼接起来,结果为E:Projectpythonday3moduledirname
    58 
    59 os.path.getatime(path) #返回path所指向的文件或目录的最后存取时间
    60 
    61 os.path.getmtime(path) #返回path所指向的文件或目录的最后修改时间

     4.sys模块

     1 import sys
     2 #com=sys.argv        #命令行参数list,第一个元素是程序本身路径
     3 #com1=com[1]
     4 
     5 #sys.exit(n) #退出程序,正常退出时exit(0)
     6 
     7 #sys.version #获取python解释器程序的版本信息
     8 
     9 #sys.path    #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量中的值
    10 
    11 #res=sys.platform
    12 #print(res)  #返回操作系统平台名称
    13 
    14 #实现一个简单的进度条
    15 import time
    16 def jindu(string):
    17     for i in range(100):
    18         sys.stdout.write(string) #使用标准输出向控制台输出
    19         time.sleep(0.1)
    20         sys.stdout.flush()#每循环一次就将字符刷新到控制台,否则会等到最后一一起刷出来
    21 
    22 jindu('#')

    5.json

     1 #dic={'name':'hello','age':13}
     2 #需求:需要将该字典的内容按照数据格式存入文件中,然后再按照数据格式从文件中读取出来
     3 #1.按照字典的格式读入文件中,因为文件只能以字符串的格式读取文件,因此需要将字典转为字符串
     4 # str_dic=str(dic)
     5 # with open('test.txt','w',encoding='utf-8') as f:
     6 #     f.write(str_dic)
     7 #
     8 # #2.将文件中的内容读取出来,并转化为字符串的形式
     9 #
    10 # with open('test.txt','r',encoding='utf-8') as f:
    11 #     data=f.read()   #data读取出来的是一个字符串,需要转化为字典
    12 #
    13 # data_dic=eval(data) #利用eval提取出字符串中的数据结构
    14 
    15 
    16 #------上面的功能可以使用json模块更简单的实现
    17 import json
    18 dic={'name':'hello','age':13}
    19 dic_json=json.dumps(dic)    #dumps函数会把所有的数据类型保持数据结构,然后整体转为标准字符串格式(双引号格式)
    20                             #dic_json={"name":"hello","age":13}这样转之后就能在不同的编程语言之间传输,数据类型是字符串
    21 
    22 int_json=json.dumps(8)      #int_json=8,字符串类型
    23 
    24 #with open('new.txt','w',encoding='utf-8') as f:
    25 #   f.write(dic_json)      #json.dumps已经直接将字典转为了字符串,可以直接写入文件
    26                            #该句等价于 json.dump(dic,f),dump只能用来处理文件
    27 
    28 
    29 with open('new.txt','r',encoding='utf-8') as f:
    30     data=json.loads(f.read())   #该句等价于json.load(f) load只能处理文件,解析出文件中数据的数据结构
    31 
    32 print(type(data))   #数据类型是字典

    6.pickle

     1 import pickle       #pickle用法与json完全一致,但是pickle可以解析函数和类,而json只能解析到字典这一层,但是json可以跨语言,pickle只能python使用
     2 
     3 dic={'name':'zhangsan','age':12}
     4 
     5 dic_pickle=pickle.dumps(dic)
     6 
     7 with open('new1.txt','wb') as f:    #注意pickle是将数据转为字节的格式,因此读写文件需要以b模式
     8     f.write(dic_pickle)
     9 
    10 with open('new1.txt','rb') as f:
    11     data=pickle.loads(f.read())
    12 
    13 print(data)

    7.shelve

     1 import shelve
     2 
     3 f=shelve.open(r'shelve.txt')    #以追加的模式打开,会创建shelve.txt.bak
     4                                 #shelve.txt.bat,shelve.txt.dir三个文件
     5 
     6 f['stu1_info']={'name':'zhangsan','age':19} #以字典的形式向文件中写入数据
     7 f['stu2_info']={'name':'zhangsan1','age':29}
     8 f['stu3_info_info']={'name':'zhangsan3','age':39}
     9 f['stu4_info_info']={'name':'zhangsan5','age':49}
    10 f['stu5_info_info']={'name':'zhangsan6','age':59}
    11 f['stu6_info_info']={'name':'zhangsan7','age':69}
    12 
    13 
    14 f.close()

    8.XML

     1 import xml.etree.ElementTree as ET
     2 
     3 tree=ET.parse("xml_lesson") #解析xml文档树
     4 root=tree.getroot() #获取根节点对象
     5 print(root.tag)  #返回根节点的名字
     6 #
     7 # for i in root:
     8 #     #print(i.tag)    #返回root节点的所有子节点的名字
     9 #     #print(i.attrib) #返回root节点子节点的属性名和属性名称,以字典的形式返回
    10 #     for j in i:
    11 #         #print(j.tag)    #返回i的子节点的名字
    12 #         #print(j.attrib) #返回i的子节点的属性名和属性内容
    13 #         #print(j.text)
    14 
    15 
    16 #遍历xml文档
    17 
    18 # for child in root:
    19 #     print(child.tag,child.attrib)
    20 #     for i in child:
    21 #         print(i.tag,i.attrib,i.text)
    22 
    23 #只遍历所有的year:
    24 # for node in root.iter("year"):
    25 #     print(node.tag,node.attrib,node.text)
    26 
    27 #修改:
    28 
    29 # for node in root.iter("year"):
    30 #     new_year=int(node.text)+1
    31 #     node.text=str(new_year)
    32 #     node.set("update","yes")
    33 #
    34 # tree.write('xml_new')
    35 
    36 #删除:
    37 # for country in root.findall("country"):
    38 #     rank=int(country.find("rank").text)
    39 #     if rank>60:
    40 #         root.remove(country)
    41 #
    42 # tree.write('output.txt')
    43 new_xml=ET.Element('namelist')
    44 name=ET.SubElement(new_xml,"name",attrib={"enrrold":"yes"})
    45 age=ET.SubElement(name,"age",attrib={"age1":"No"})
    46 sex=ET.SubElement(name,"sex")
    47 sex.text="male"
    48 
    49 et=ET.ElementTree(new_xml)
    50 et.write('new_xml',encoding='utf-8',xml_declaration=True)

    9.re

      1 import re
      2 
      3 #-------------元字符: .^$*+?{}[]|()---------------------
      4 #.匹配任意字符,一个.代表一个字符
      5 
      6 res=re.findall("a.c","abcdefbfesafhircarc") #匹配到abc 和arc,
      7 res=re.findall("a..","adbuwebfwaeeddefqaawde")#匹配到adb,aee,aaw
      8 #匹配三个字符,以a开头,后面两个字符是任意字符
      9 
     10 #^匹配在字符串开始
     11 res=re.findall("^a.b","acbdefadbaebatb") #只返回acb
     12 res=re.findall("^a.b","diewadb")        #返回空列表
     13 
     14 #$只在字符串结尾匹配
     15 res=re.findall("a.b$","adbsdjeatacb")#匹配到acb,不会匹配adb
     16 
     17 #* 匹配字符,字符可以在字符串中出现任意次(0~无穷)
     18 res=re.findall("ab*","abbbbbcweferfer") #匹配到abbbbb
     19 res=re.findall("ab*","acdferbxiw")  #匹配到a(b可以出现0次
     20 
     21 #+ 匹配字符,字符在字符串中出现大于0次(1~无穷)
     22 res=re.findall("ab+","abbbbbcweferfer") #匹配到abbbbb
     23 res=re.findall("ab+","acdferbxiw")  #返回空列表,ab要至少出现一次才行
     24 
     25 #?匹配字符,字符在字符串中出现次数不大于1(0-1)
     26 res=re.findall("ab?","abbbbbcweferfera") #匹配到ab,a出现的次数不能超过一次,如果b出现多次,只保留一个
     27 res=re.findall("ab?","acdferbxiw")  #匹配到a(b可以出现0次
     28 
     29 #{}匹配字符,指定字符在字符串中出现的次数
     30 res=re.findall("ab{6}","abbbbbbcewidw")#b出现6次
     31 res=re.findall("ab{1,6}","abdweabbdwedbabbbbbbbbbc")#b出现的次数为1-6次,如果出现的次数超过6次,只保留6个b
     32 
     33 #[]字符集,字符集里面只有三个功能符号- ^ \,其他所有符号都是普通符号(包括前面的元字符)
     34 ######- 表示匹配的范围
     35 res=re.findall("a[a-zA-Z]b","abbdfanieaGbo")#匹配所有以a开头,b结尾,第二个字符是字母的字符串
     36 res=re.findall("a[0-9]b","a9bureba0b")#匹配所有第二个字符为数子
     37 res=re.findall("a[0-9]+b","a990b")#ab中间有多个数字
     38 
     39 ######^表示非,即除去这些字符之外的字符
     40 res=re.findall("a[^0-9]b","adb")#ab之间不能是数字
     41 
     42 #####元字符在字符集中只是普通字符
     43 res=re.findall("a[.]b","a.bvsdadb")#只能匹配到a.b,不会匹配到adb,这里的.就是一个普通字符
     44 
     45 #转义字符
     46 ########d匹配十进制数字
     47 res=re.findall("adb","a2basb")#ab之间是一个数字
     48 res=re.findall("ad+b","a12ba34ba56b")#ab之间是多个数字
     49 
     50 ########D匹配任何非数字字符,相当于类[^0-9]
     51 res=re.findall("aDb","adbadbarba0b")#ab之间不能是数字
     52 
     53 ########w匹配任何的数字和字符,相当于[a-zA-Z0-9]
     54 res=re.findall("aw","a0badb")#ab之间可以是字母或数字
     55 
     56 ########W匹配任何的非数字和字母,相当于[^a-zA-Z0-9]
     57 res=re.findall("aWb","a%ba#b")#ab之间不可以是数字和字母
     58 
     59 ########s匹配任何空白字符,它相当于[	
    
    fv].
     60 res=re.findall("asb","a
    ba b afb")#ab之间有空白符的特殊字符或者空格
     61 
     62 ########S匹配任何的非空白字符
     63 res=re.findall("aSb","ababababs")
     64 
     65 #######匹配一个特殊的字符边界,比如空格,#,&等
     66 res=re.findall("I\b","I am aLIst")
     67 res=re.findall(r"I","I am aLIst")  #注意,因为在python中具有特殊的意义,
     68                                      #因此需要使用r表示原生字符(不会被解释器将替换掉,或者使用将转义,
     69 
     70 ########的特殊符号处理
     71 #在python中,有一些是有特殊意义的,比如	,等,如果写正则表达式使用了这些符号,那么python解释器会将这些符号替换成其所代表的特殊意义
     72 #这样,在正则模块中,正则表达式的含义就会发生变化,同时,进入正则·模块后,可能也有一些特殊意义,因此正则表达式可能也会将其替换成她所代表的
     73 #意义,这样一来,正则表达式的含义也会发生变化,因此可能会出现要我们使用进行两次转义操作
     74 
     75 res=re.findall("c\\l","abccle")
     76 ###上面的表达式,本来是想匹配l的,但是因为l是特殊字符,因此需要将l改成\l做一次转义,然后
     77 ###在正则模块中和l也是有特殊含义的,因此还需要对和l也做一次转义操作,这样就有\\四个符号
     78 ###最后匹配结果会是\l
     79 
     80 #|或,两个字符中选择一个
     81 res=re.findall("ab|cd","abdacdaedabcd")#匹配ab或者cd
     82 res=re.findall("a(?:b|c)d","abdacdaedbcds")#匹配abd或者acd
     83 
     84 #()分组
     85 res=re.findall("(abc)+","abcabcabc")#将abc作为整体,出现多次,这种情况下会返回匹配到的括号里面的内容(优先只展示括号内的内容),即只有abc
     86 res=re.findall("(?:abc)+","abcabcabc")#取消掉括号的优先级,这样就会返回abcabcabc
     87 
     88 
     89 #--------------------re模块的常见方法
     90 
     91 #re.findall()#以列表的形式返回匹配到的所有字符
     92 
     93 
     94 #re.search()#只返回匹配到的第一个字符串,即使可以匹配多个,也只是返回第一个
     95 #re.search().group()#注意,search只是返回了一个地址,需要调用group方法才能提取到值
     96 res=re.search("(?P<name>[a-z]+)(?P<age>d+)","alex34nihao45heheh45")#?p<name>表示将匹配到的字符串放入组为name的组中
     97 
     98 #re.match()#功能和search类似,但是只会匹配字符串开始位置。
     99 
    100 res=re.split('[ab]','abcd')#先按照a将字符串分割为' '和'bcd',再讲bcd按照b分割成''和cd,因此最后返回的是['','' ,'cd']
    101 
    102 res=re.sub('d','abc','alvin56yuan68')#第一个参数是匹配规则,第二个参数是用来替代的字符串,第三个参数是原字符串
    103                                       #该命名执行结果是将第三个参数中的所有数字替换成abc

    10.logging模块

     1 import logging
     2 
     3 #-----------------------------------logging.basicConfig
     4 # logging.basicConfig(
     5 #     level=logging.DEBUG,
     6 #     filename="logger.log",
     7 #     filemode="w",
     8 #     format="%(asctime)s %(filename)s[%(lineno)d]  %(message)s"
     9 #
    10 #
    11 # )
    12 #
    13 # logging.debug('hello')
    14 # logging.info('hello')
    15 # logging.warning('warning message')
    16 # logging.error('error message')
    17 # logging.critical('critical message')
    18 
    19 #-----------------------------------logger
    20 # def logger():
    21 #     logger=logging.getLogger()
    22 #
    23 #
    24 #     fh=logging.FileHandler("test_log")
    25 #     #ch=logging.StreamHandler()
    26 #
    27 #     fm=logging.Formatter("%(asctime)s  %(message)s")
    28 #
    29 #     fh.setFormatter(fm)
    30 #     #ch.setFormatter(fm)
    31 #
    32 #     logger.addHandler(fh)
    33 #     #logger.addHandler(ch)
    34 #     logger.setLevel("DEBUG")
    35 #
    36 #     return logger
    37 # #----------------------
    38 # logger=logger()
    39 #
    40 # logger.debug("debug")
    41 # logger.info("info")
    42 # logger.warning("warning")
    43 # logger.error("error")
    44 # logger.critical("critical")
    45 #--------------------------------------------------
    46 import logging
    47 
    48 logger=logging.getLogger()
    49 
    50 
    51 logger1 = logging.getLogger('mylogger')
    52 logger1.setLevel(logging.DEBUG)
    53 
    54 # logger2 = logging.getLogger('mylogger')
    55 # logger2.setLevel(logging.WARNING)
    56 
    57 
    58 fh=logging.FileHandler("test_log-new")
    59 ch=logging.StreamHandler()
    60 
    61 # logger.addHandler(ch)
    62 # logger.addHandler(fh)
    63 
    64 logger1.addHandler(fh)
    65 logger1.addHandler(ch)
    66 
    67 # logger2.addHandler(fh)
    68 # logger2.addHandler(ch)
    69 
    70 
    71 # logger.debug('logger debug message')
    72 # logger.info('logger info message')
    73 # logger.warning('logger warning message')
    74 # logger.error('logger error message')
    75 # logger.critical('logger critical message')
    76 
    77 # logger1.debug('logger1 debug message')
    78 # logger1.info('logger1 info message')
    79 # logger1.warning('logger1 warning message')
    80 # logger1.error('logger1 error message')
    81 # logger1.critical('logger1 critical message')
    82 
    83 # logger2.debug('logger2 debug message')
    84 # logger2.info('logger2 info message')
    85 # logger2.warning('logger2 warning message')
    86 # logger2.error('logger2 error message')
    87 # logger2.critical('logger2 critical message')

    11.configparse模块:

     1 import configparser
     2 
     3 # config=configparser.ConfigParser()  #config={}
     4 #
     5 # config["DEFAULT"]={"Severlink":'45',
     6 #                     "Compreesion":'yes',
     7 #                     "CompreesionLevel":'9'
     8 #                    }
     9 #
    10 # config['bitbucket.org']={}
    11 #
    12 # config['bitbucket.org']['User']='hg'
    13 #
    14 # config['topsercet.com']={}
    15 #
    16 # topsercet=config['topsercet.com']
    17 # topsercet['Hot pred']='50022'
    18 # topsercet['niha']='xoex'
    19 #
    20 # with open('test.txt','w',encoding='utf-8') as f:
    21 #     config.write(f)
    22 
    23 #----------------------增删改查-----------------
    24 #config文件当做字典处理即可
    25 config=configparser.ConfigParser()
    26 print(config.sections())  #[]
    27 config.read('test.txt')
    28 print(config.sections())    #读取配置文件中的key值,不读取DEFAULT以列表的形式返回
    29 ''
    30 print('a' in config)
    31 print('bitbucket.org' in config)  #判断某个key值是否在配置文件中
    32 print(config['bitbucket.org']["User"]) #hg
    33 
    34 #遍历配置文件
    35 for key in config:
    36     print(key)
    37 
    38 for key in config['bitbucket.org']:
    39     print(key)
    40 
    41 
    42 res=config.options('bitbucket.org')#返回bitbucket和DEFAULT的所有key值
    43 res=config.items('bitbucket.org')#以键值对的方式返回bitbucket和DEFAULT的所有值
    44 res=config.get('bitbucket.org','compreesion')#yes,判断key值是否在某一个字典中
    45 
    46 
    47 config.add_section('yuan') #赠加一个section模块,即key值
    48 config.set('yuan','key1','1111')  #增加一个setion到一个新文件中
    49 
    50 config.write(open('new.txt','w'))#将增加的内容和原来的内容一起写入新文件中
    51 
    52 config.remove_section('yuan')   #删除一个setion
    53 config.remove_option('bitbucket.org','User')    #删除一个option
    54 config.write(open('new1_txt','w'))
    55 print('------',res)

    12.hashlib

    1 import hashlib
    2 
    3 obj=hashlib.md5()
    4 obj.update('hello'.encode('utf-8'))  #将hello按照utf-8编码方式加密,单向
    5 res=obj.hexdigest()#生成密文
    6 print(res)
  • 相关阅读:
    Security headers quick reference Learn more about headers that can keep your site safe and quickly look up the most important details.
    Missing dollar riddle
    Where Did the Other Dollar Go, Jeff?
    proteus 与 keil 联调
    cisco router nat
    router dhcp and dns listen
    配置802.1x在交换机的端口验证设置
    ASAv931安装&初始化及ASDM管理
    S5700与Cisco ACS做802.1x认证
    playwright
  • 原文地址:https://www.cnblogs.com/jiachuantang/p/8406238.html
Copyright © 2011-2022 走看看