??????
目录一引子二数字类型int与float2.3使用7.4.1关系运算7.5练习
??????一引子数据类型是用来记录事物状态的,而事物的状态是不断变化的(如:一个人年龄的增长(操作int类型),单个人名的修改(操作str类型),学生列表中增加学生(操作list类型)等),这意味着我们在开发程序时需要频繁对数据进行操作,为了提升我们的开发效率,python针对这些常用的操作,为每一种数据类型内置了一系列方法。本章的主题就是带大家详细了解下它们,以及每种数据类型的详细定义、类型转换。
二数字类型int与float##2.1定义
#1、定义:#1.1整型int的定义age=10#本质age=int(10)#1.2浮点型float的定义salary=.3#本质salary=float(.3)#注意:名字+括号的意思就是调用某个功能,比如#print(...)调用打印功能#int(...)调用创建整型数据的功能#float(...)调用创建浮点型数据的功能
##2.2类型转换
#1、数据类型转换#1.1int可以将由纯整数构成的字符串直接转换成整型,若包含其他任意非整数符号,则会报错s=res=int(s)res,type(res)(,classint)int(12.3)#错误演示:字符串内包含了非整数符号.Traceback(mostrecentcalllast):File"stdin",line1,inmoduleValueError:invalidliteralforint()withbase10:12.3#1.2进制转换#十进制转其他进制bin(3)0b11oct(9)0o11hex(17)0x11#其他进制转十进制int(0b11,2)3int(0o11,8)9int(0x11,16)17#1.3float同样可以用来做数据类型的转换s=12.3res=float(s)res,type(res)(12.3,classfloat)2.3使用
数字类型主要就是用来做数学运算与比较运算,因此数字类型除了与运算符结合使用之外,并无需要掌握的内置方法
#三字符串
##3.1定义:
#定义:在单引号\双引号\三引号内包含一串字符name1=jason#本质:name=str(任意形式内容)name2="lili"#本质:name=str("任意形式内容")name3="""ricky"""#本质:name=str("""任意形式内容""")
##3.2类型转换
#数据类型转换:str()可以将任意数据类型转换成字符串类型,例如type(str([1,2,3]))#list-strclassstrtype(str({"name":"jason","age":18}))#dict-strclassstrtype(str((1,2,3)))#tuple-strclassstrtype(str({1,2,3,4}))#set-strclassstr
###3.3.1优先掌握的操作
str1=hellopython!#1.按索引取值(正向取,反向取):#1.1正向取(从左往右)str1[6]p#1.2反向取(负号表示从右往左)str1[-4]h#1.3对于str来说,只能按照索引取值,不能改str1[0]=H#报错TypeError#2.切片(顾头不顾尾,步长)#2.1顾头不顾尾:取出索引为0到8的所有字符str1[0:9]hellopyt#2.2步长:0:9:2,第三个参数2代表步长,会从0开始,每次累加一个2即可,所以会取出索引0、2、4、6、8的字符str1[0:9:2]hlopt#2.3反向切片str1[::-1]#-1表示从右往左依次取值!nohtypolleh#3.长度len#3.1获取字符串的长度,即字符的个数,但凡存在于引号内的都算作字符)len(str1)#空格也算字符13#4.成员运算in和notin#4.1int:判断hello是否在str1里面helloinstr1True#4.2notin:判断tony是否不在str1里面tonynotinstr1True#5.strip移除字符串首尾指定的字符(默认移除空格)#5.1括号内不指定字符,默认移除首尾空白字符(空格、\n、\t)str1=lifeisshort!str1.strip()lifeisshort!#5.2括号内指定字符,移除首尾指定的字符str2=**tony**str2.strip(*)tony#6.切分split#6.1括号内不指定字符,默认以空格作为切分符号str3=helloworldstr3.split()[hello,world]#6.2括号内指定分隔字符,则按照括号内指定的字符切割字符串str4=.0.0.1str4.split(.)[,0,0,1]#注意:split切割得到的结果是列表数据类型#7.循环str5=今天你好吗?forlineinstr5:#依次取出字符串中每一个字符...print(line)...今天你好吗?
###3.3.2需要掌握的操作
1.strip,lstrip,rstrip
str1=**tony***str1.strip(*)#移除左右两边的指定字符tonystr1.lstrip(*)#只移除左边的指定字符tony***str1.rstrip(*)#只移除右边的指定字符**tony
2.lower(),upper()
str2=MynAmeistonY!str2.lower()#将英文字符串全部变小写mynameistony!str2.upper()#将英文字符串全部变大写MYNAMEISTONY!
3.startswith,endswith
str3=tonyjam#startswith()判断字符串是否以括号内指定的字符开头,结果为布尔值True或Falsestr3.startswith(t)Truestr3.startswith(j)False#endswith()判断字符串是否以括号内指定的字符结尾,结果为布尔值True或Falsestr3.endswith(jam)Truestr3.endswith(tony)False
4.格式化输出之format
之前我们使用%s来做字符串的格式化输出操作,在传值时,必须严格按照位置与%s一一对应,而字符串的内置方法format则提供了一种不依赖位置的传值方式
案例:
#format括号内在传参数时完全可以打乱顺序,但仍然能指名道姓地为指定的参数传值,name=‘tony’就是传给{name}str4=mynameis{name},myageis{age}!.format(age=18,name=tony)str4mynameistony,myageis18!str4=mynameis{name}{name}{name},myageis{name}!.format(name=tony,age=18)str4mynameistonytonytony,myageistony!
format的其他使用方式(了解)
#类似于%s的用法,传入的值会按照位置与{}一一对应str4=mynameis{},myageis{}!.format(tony,18)str4mynameistony,myageis18!
#把format传入的多个值当作一个列表,然后用{索引}取值str4=mynameis{0},myageis{1}!.format(tony,18)str4mynameistony,myageis18!str4=mynameis{1},myageis{0}!.format(tony,18)str4mynameis18,myageistony!str4=mynameis{1},myageis{1}!.format(tony,18)str4mynameis18,myageis18!
5.split,rsplit
#split会按照从左到右的顺序对字符串进行切分,可以指定切割次数str5=C:/a/b/c/d.txtstr5.split(/,1)[C:,a/b/c/d.txt]#rsplit刚好与split相反,从右往左切割,可以指定切割次数str5=a
b
cstr5.rsplit(
,1)[a
b,c]
6.join
#从可迭代对象中取出多个字符串,然后按照指定的分隔符进行拼接,拼接的结果为字符串%.join(hello)#从字符串hello中取出多个字符串,然后按照%作为分隔符号进行拼接h%e%l%l%o
.join([tony,18,read])#从列表中取出多个字符串,然后按照*作为分隔符号进行拼接tony
18
read
7.replace
#用新的字符替换字符串中旧的字符str7=mynameistony,myageis18!#将tony的年龄由18岁改成73岁str7=str7.replace(18,73)#语法:replace(旧内容,新内容)str7mynameistony,myageis73!#可以指定修改的个数str7=mynameistony,myageis18!str7=str7.replace(my,MY,1)#只把一个my改为MYstr7MYnameistony,myageis18!
8.isdigit
#判断字符串是否是纯数字组成,返回结果为True或Falsestr8=str8.isdigit()Truestr8=gstr8.isdigit()False
###3.3.3了解操作
#1.find,rfind,index,rindex,count#1.1find:从指定范围内查找子字符串的起始索引,找得到则返回数字1,找不到则返回-1msg=tonysayhellomsg.find(o,1,3)#在索引为1和2(顾头不顾尾)的字符中查找字符o的索引1#1.2index:同find,但在找不到时会报错msg.index(e,2,4)#报错ValueError#1.3rfind与rindex:略#1.4count:统计字符串在大字符串中出现的次数msg="helloeveryone"msg.count(e)#统计字符串e出现的次数4msg.count(e,1,6)#字符串e在索引1~5范围内出现的次数1#2.center,ljust,rjust,zfillname=tonyname.center(30,-)#总宽度为30,字符串居中显示,不够用-填充-------------tony-------------name.ljust(30,*)#总宽度为30,字符串左对齐显示,不够用*填充tony**************************name.rjust(30,*)#总宽度为30,字符串右对齐显示,不够用*填充**************************tonyname.zfill(50)#总宽度为50,字符串右对齐显示,不够用0填充tony#3.expandtabsname=tony\thello#\t表示制表符(tab键)nametonyhelloname.expandtabs(1)#修改\t制表符代表的空格数tonyhello#4.captalize,swapcase,title#4.1captalize:首字母大写message=helloeveryonenicetomeetyou!message.capitalize()Helloeveryonenicetomeetyou!#4.2swapcase:大小写翻转message1=Higirl,Iwantmakefriendswithyou!message1.swapcase()hIGIRL,iWANTMAKEFRIENDSWITHYOU!#4.3title:每个单词的首字母大写msg=dearmyfriendimissyouverymuchmsg.title()DearMyFriendIMissYouVeryMuch#5.is数字系列#在python3中num1=b4#bytesnum2=u4#unicode,python3中无需加u就是unicodenum3=四#中文数字num4=Ⅳ#罗马数字#isdigt:bytes,unicodenum1.isdigit()Truenum2.isdigit()Truenum3.isdigit()Falsenum4.isdigit()False#isdecimal:uncicode(bytes类型无isdecimal方法)num2.isdecimal()Truenum3.isdecimal()Falsenum4.isdecimal()False#isnumberic:unicode,中文数字,罗马数字(bytes类型无isnumberic方法)num2.isnumeric()Truenum3.isnumeric()Truenum4.isnumeric()True#三者不能判断浮点数num5=4.3num5.isdigit()Falsenum5.isdecimal()Falsenum5.isnumeric()False总结:最常用的是isdigit,可以判断bytes和unicode类型,这也是最常见的数字应用场景如果要判断中文数字或罗马数字,则需要用到isnumeric。#6.is其他name=tonyname.isalnum()#字符串中既可以包含数字也可以包含字母Truename.isalpha()#字符串中只包含字母Falsename.isidentifier()Truename.islower()#字符串是否是纯小写Truename.isupper()#字符串是否是纯大写Falsename.isspace()#字符串是否全是空格Falsename.istitle()#字符串中的单词首字母是否都是大写False
#四列表
##4.1定义
#定义:在[]内,用逗号分隔开多个任意数据类型的值l1=[1,a,[1,2]]#本质:l1=list([1,a,[1,2]])
##4.2类型转换
#但凡能被for循环遍历的数据类型都可以传给list()转换成列表类型,list()会跟for循环一样遍历出数据类型中包含的每一个元素然后放到列表中list(wdad)#结果:[w,d,a,d]list([1,2,3])#结果:[1,2,3]list({"name":"jason","age":18})#结果:[name,age]list((1,2,3))#结果:[1,2,3]list({1,2,3,4})#结果:[1,2,3,4]
##4.3使用
###4.3.1优先掌握的操作
#1.按索引存取值(正向存取+反向存取):即可存也可以取#1.1正向取(从左往右)my_friends=[tony,jason,tom,4,5]my_friends[0]tony#1.2反向取(负号表示从右往左)my_friends[-1]5#1.3对于list来说,既可以按照索引取值,又可以按照索引修改指定位置的值,但如果索引不存在则报错my_friends=[tony,jack,jason,4,5]my_friends[1]=martthowmy_friends[tony,martthow,jason,4,5]#2.切片(顾头不顾尾,步长)#2.1顾头不顾尾:取出索引为0到3的元素my_friends[0:4][tony,jason,tom,4]#2.2步长:0:4:2,第三个参数2代表步长,会从0开始,每次累加一个2即可,所以会取出索引0、2的元素my_friends[0:4:2][tony,tom]#3.长度len(my_friends)5#4.成员运算in和notintonyinmy_friendsTruexxxnotinmy_friendsTrue#5.添加#5.1append()列表尾部追加元素l1=[a,b,c]l1.append(d)l1[a,b,c,d]#5.2extend()一次性在列表尾部添加多个元素l1.extend([a,b,c])l1[a,b,c,d,a,b,c]#5.3insert()在指定位置插入元素l1.insert(0,"first")#0表示按索引位置插值l1[first,a,b,c,alisa,a,b,c]#6.删除#6.1dell=[11,22,33,44]dell[2]#删除索引为2的元素l[11,22,44]#6.2pop()默认删除列表最后一个元素,并将删除的值返回,括号内可以通过加索引值来指定删除元素l=[11,22,33,22,44]res=l.pop()res44res=l.pop(1)res22#6.3remove()括号内指名道姓表示要删除哪个元素,没有返回值l=[11,22,33,22,44]res=l.remove(22)#从左往右查找第一个括号内需要删除的元素print(res)None#7.reverse()颠倒列表内元素顺序l=[11,22,33,44]l.reverse()l[44,33,22,11]#8.sort()给列表内所有元素排序#8.1排序时列表元素之间必须是相同数据类型,不可混搭,否则报错l=[11,22,3,42,7,55]l.sort()l[3,7,11,22,42,55]#默认从小到大排序l=[11,22,3,42,7,55]l.sort(reverse=True)#reverse用来指定是否跌倒排序,默认为Falsel[55,42,22,11,7,3]#8.2了解知识:#我们常用的数字类型直接比较大小,但其实,字符串、列表等都可以比较大小,原理相同:都是依次比较对应位置的元素的大小,如果分出大小,则无需比较下一个元素,比如l1=[1,2,3]l2=[2,]l2l1True#字符之间的大小取决于它们在ASCII表中的先后顺序,越往后越大s1=abcs2=azs2s1#s1与s2的第一个字符没有分出胜负,但第二个字符zb,所以s2s1成立True#所以我们也可以对下面这个列表排序l=[A,z,adjk,hello,hea]l.sort()l[A,adjk,hea,hello,z]#9.循环#循环遍历my_friends列表里面的值forlineinmy_friends:print(line)tonyjackjason45
###4.3.2了解操作
l=[1,2,3,4,5,6]l[0:3:1][1,2,3]#正向步长l[2::-1][3,2,1]#反向步长#通过索引取值实现列表翻转l[::-1][6,5,4,3,2,1]
#五元组
##5.1作用元组与列表类似,也是可以存多个任意类型的元素,不同之处在于元组的元素不能修改,即元组相当于不可变的列表,用于记录多个固定不允许修改的值,单纯用于取
##5.2定义方式
#在()内用逗号分隔开多个任意类型的值countries=("中国","美国","英国")#本质:countries=tuple("中国","美国","英国")#强调:如果元组内只有一个值,则必须加一个逗号,否则()就只是包含的意思而非定义元组countries=("中国",)#本质:countries=tuple("中国")
##5.3类型转换
#但凡能被for循环的遍历的数据类型都可以传给tuple()转换成元组类型tuple(wdad)#结果:(w,d,a,d)tuple([1,2,3])#结果:(1,2,3)tuple({"name":"jason","age":18})#结果:(name,age)tuple((1,2,3))#结果:(1,2,3)tuple({1,2,3,4})#结果:(1,2,3,4)#tuple()会跟for循环一样遍历出数据类型中包含的每一个元素然后放到元组中
##5.4使用
tuple1=(1,hhaha,.00,11,22,33)#1、按索引取值(正向取+反向取):只能取,不能改否则报错!tuple1[0]1tuple1[-2]22tuple1[0]=hehe#报错:TypeError:#2、切片(顾头不顾尾,步长)tuple1[0:6:2](1,.0,22)#3、长度len(tuple1)6#4、成员运算in和notinhhahaintuple1Truehhahanotintuple1False#5、循环forlineintuple1:...print(line)1hhaha.
#六字典
##6.1定义方式
#定义:在{}内用逗号分隔开多元素,每一个元素都是key:value的形式,其中value可以是任意类型,而key则必须是不可变类型,详见第八小节,通常key应该是str类型,因为str类型会对value有描述性的功能info={name:tony,age:18,sex:male}#本质info=dict({....})#也可以这么定义字典info=dict(name=tony,age=18,sex=male)#info={age:18,sex:male,name:tony}
##6.2类型转换
#转换1:info=dict([[name,tony],(age,18)])info{age:18,name:tony}#转换2:fromkeys会从元组中取出每个值当做key,然后与None组成key:value放到字典中{}.fromkeys((name,age,sex),None){age:None,sex:None,name:None}
##6.3使用
###6.3.1优先掌握的操作
#1、按key存取值:可存可取#1.1取dic={...name:xxx,...age:18,...hobbies:[playgame,basketball]...}dic[name]xxxdic[hobbies][1]basketball#1.2对于赋值操作,如果key原先不存在于字典,则会新增key:valuedic[gender]=maledic{name:tony,age:18,hobbies:[playgame,basketball],gender:male}#1.3对于赋值操作,如果key原先存在于字典,则会修改对应value的值dic[name]=tonydic{name:tony,age:18,hobbies:[playgame,basketball]}#2、长度lenlen(dic)3#3、成员运算in和notinnameindic#判断某个值是否是字典的keyTrue#4、删除dic.pop(name)#通过指定字典的key来删除字典的键值对dic{age:18,hobbies:[playgame,basketball]}#5、键keys(),值values(),键值对items()dic={age:18,hobbies:[playgame,basketball],name:xxx}#获取字典所有的keydic.keys()dict_keys([name,age,hobbies])#获取字典所有的valuedic.values()dict_values([xxx,18,[playgame,basketball]])#获取字典所有的键值对dic.items()dict_items([(name,xxx),(age,18),(hobbies,[playgame,basketball])])#6、循环#6.1默认遍历的是字典的keyforkeyindic:...print(key)...agehobbiesname#6.2只遍历keyforkeyindic.keys():...print(key)...agehobbiesname#6.3只遍历valueforkeyindic.values():...print(key)...18[playgame,basketball]xxx#6.4遍历key与valueforkeyindic.items():...print(key)...(age,18)(hobbies,[playgame,basketball])(name,xxx)
###6.3.2需要掌握的操作
1.get()
dic={k1:jason,k2:Tony,k3:JY}dic.get(k1)jason#key存在,则获取key对应的value值res=dic.get(xxx)#key不存在,不会报错而是默认返回Noneprint(res)Noneres=dic.get(xxx,)#key不存在时,可以设置默认返回的值print(res)#ps:字典取值建议使用get方法
2.pop()
dic={k1:jason,k2:Tony,k3:JY}v=dic.pop(k2)#删除指定的key对应的键值对,并返回值dic{k1:jason,kk2:JY}vTony
3.popitem()
dic={k1:jason,k2:Tony,k3:JY}item=dic.popitem()#随机删除一组键值对,并将删除的键值放到元组内返回dic{k3:JY,k2:Tony}item(k1,jason)
4.update()
#用新字典更新旧字典,有则修改,无则添加dic={k1:jason,k2:Tony,k3:JY}dic.update({k1:JN,k4:xxx})dic{k1:JN,k3:JY,k2:Tony,k4:xxx}
5.fromkeys()
dic=dict.fromkeys([k1,k2,k3],[])dic{k1:[],k2:[],k3:[]}
6.setdefault()
#key不存在则新增键值对,并将新增的value返回dic={k1:,k2:}res=dic.setdefault(k3,)resdic#字典中新增了键值对{k1:,k3:,k2:}#key存在则不做任何修改,并返回已存在key对应的value值dic={k1:,k2:}res=dic.setdefault(k1,)resdic#字典不变{k1:,k2:}
#七集合
##7.1作用集合、list、tuple、dict一样都可以存放多个值,但是集合主要用于:去重、关系运算
##7.2定义
"""定义:在{}内用逗号分隔开多个元素,集合具备以下三个特点:1:每个元素必须是不可变类型2:集合内没有重复的元素3:集合内元素无序"""s={1,2,3,4}#本质s=set({1,2,3,4})#注意1:列表类型是索引对应值,字典是key对应值,均可以取得单个指定的值,而集合类型既没有索引也没有key与值对应,所以无法取得单个的值,而且对于集合来说,主要用于去重与关系元素,根本没有取出单个指定值这种需求。#注意2:{}既可以用于定义dict,也可以用于定义集合,但是字典内的元素必须是key:value的格式,现在我们想定义一个空字典和空集合,该如何准确去定义两者?d={}#默认是空字典s=set()#这才是定义空集合
##7.3类型转换
#但凡能被for循环的遍历的数据类型(强调:遍历出的每一个值都必须为不可变类型)都可以传给set()转换成集合类型s=set([1,2,3,4])s1=set((1,2,3,4))s2=set({name:jason,})s3=set(egon)s,s1,s2,s3{1,2,3,4}{1,2,3,4}{name}{e,o,g,n}
##7.4使用
7.4.1关系运算我们定义两个集合friends与friends2来分别存放两个人的好友名字,然后以这两个集合为例讲解集合的关系运算
friends1={"zero","kevin","jason","egon"}#用户1的好友们friends2={"Jy","ricky","jason","egon"}#用户2的好友们
两个集合的关系如下图所示
插图:示范集合插图
#1.合集/并集(
):求两个用户所有的好友(重复好友只留一个)friends1
friends2{kevin,ricky,zero,jason,Jy,egon}#2.交集():求两个用户的共同好友friends1friends2{jason,egon}#3.差集(-):friends1-friends2#求用户1独有的好友{kevin,zero}friends2-friends1#求用户2独有的好友{ricky,Jy}#4.对称差集(^)#求两个用户独有的好友们(即去掉共有的好友)friends1^friends2{kevin,zero,ricky,Jy}#5.值是否相等(==)friends1==friends2False#6.父集:一个集合是否包含另外一个集合#6.1包含则返回True{1,2,3}{1,2}True{1,2,3}={1,2}True#6.2不存在包含关系,则返回False{1,2,3}{1,3,4,5}False{1,2,3}={1,3,4,5}False#7.子集{1,2}{1,2,3}True{1,2}={1,2,3}True
###7.4.2去重
集合去重复有局限性
#1.只能针对不可变类型#2.集合本身是无序的,去重之后无法保留原来的顺序
示例如下
l=[a,b,1,a,a]s=set(l)s#将列表转成了集合{b,a,1}l_new=list(s)#再将集合转回列表l_new[b,a,1]#去除了重复,但是打乱了顺序#针对不可变类型,并且保证顺序则需要我们自己写代码实现,例如l=[{name:lili,age:18,sex:male},{name:jack,age:73,sex:male},{name:tom,age:20,sex:female},{name:lili,age:18,sex:male},{name:lili,age:18,sex:male},]new_l=[]fordicinl:ifdicnotinnew_l:new_l.append(dic)print(new_l)#结果:既去除了重复,又保证了顺序,而且是针对不可变类型的去重[{age:18,sex:male,name:lili},{age:73,sex:male,name:jack},{age:20,sex:female,name:tom}]
###7.4.3其他操作
插图:恶搞图13
#1.长度s={a,b,c}len(s)3#2.成员运算cinsTrue#3.循环foritemins:...print(item)...cab7.5练习
"""一.关系运算 有如下两个集合,pythons是报名python课程的学员名字集合,linuxs是报名linux课程的学员名字集合 pythons={jason,egon,kevin,ricky,gangdan,biubiu} linuxs={kermit,tony,gangdan} 1.求出即报名python又报名linux课程的学员名字集合 2.求出所有报名的学生名字集合 3.求出只报名python课程的学员名字 4.求出没有同时这两门课程的学员名字集合"""#求出即报名python又报名linux课程的学员名字集合pythonslinuxs#求出所有报名的学生名字集合pythons
linuxs#求出只报名python课程的学员名字pythons-linuxs#求出没有同时这两门课程的学员名字集合pythons^linuxs
#八可变类型与不可变类型
可变数据类型:值发生改变时,内存地址不变,即id不变,证明在改变原值
不可变类型:值发生改变时,内存地址也发生改变,即id也变,证明是没有在改变原值,是产生了新的值
数字类型:
x=10id(x)x=20id(x)#内存地址改变了,说明整型是不可变数据类型,浮点型也一样
字符串
x="Jy"id(x)x="Ricky"id(x)#内存地址改变了,说明字符串是不可变数据类型
列表
list1=[tom,jack,egon]id(list1)list1[2]=kevinid(list1)list1.append(lili)id(list1)#对列表的值进行操作时,值改变但内存地址不变,所以列表是可变数据类型
元组
t1=("tom","jack",[1,2])t1[0]=TOM#报错:TypeErrort1.append(lili)#报错:TypeError#元组内的元素无法修改,指的是元组内索引指向的内存地址不能被修改t1=("tom","jack",[1,2])id(t1[0]),id(t1[1]),id(t1[2])(,,)t1[2][0]=#如果元组中存在可变类型,是可以修改,但是修改后的内存地址不变t1(tom,jack,[,2])id(t1[0]),id(t1[1]),id(t1[2])#查看id仍然不变(,,)
字典
dic={name:egon,sex:male,age:18}id(dic)dic[age]=19dic{age:19,sex:male,name:egon}id(dic)#对字典进行操作时,值改变的情况下,字典的id也是不变,即字典也是可变数据类型
#九数据类型总结
插图:数据类型总结
—END—上海老男孩Python高薪课程6月免费试学火热报名中,Python业内知名大咖Egon老师亲授!欢迎扫描下方