• 模块


    本文讨论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)
  • 相关阅读:
    2014找工作----扎实的基础和开阔的视野是企业最看重的因素
    2014找工作总结-机会往往留给有准备的人
    【STL源码剖析读书笔记】【第1章】STL概论与版本简介
    【c++ primer读书笔记】【第13章】拷贝控制
    【c++ primer读书笔记】【第12章】动态内存
    【c++ primer读书笔记】【第11章】关联容器
    【c++ primer读书笔记】【第10章】泛型算法
    【c++ primer读书笔记】【第9章】顺序容器
    WebSocket 是什么原理?为什么可以实现持久连接
    IDEA将项目导出war包方法(详细)
  • 原文地址:https://www.cnblogs.com/jiachuantang/p/8406238.html
Copyright © 2020-2023  润新知