閉包和裝飾器
閉包:就是在一個外函數(shù)中定義了一個內(nèi)部函數(shù),內(nèi)部函數(shù)引用了外函數(shù)的臨時變量,并且外函數(shù)的返回值就是內(nèi)函數(shù)的引用
裝飾器:本質(zhì)就是閉包,主要作用為已經(jīng)存在的對象添加額外的功能,例如日志記錄,數(shù)據(jù)校驗等
匿名函數(shù)
lambda? 通常用于需要一個函數(shù),但是又不想費神命名一個函數(shù)的時候使用,可節(jié)約內(nèi)存空間
lambda x,y:x+y? ?
lambda 后面是傳入的參數(shù) :代表return
迭代器
基礎(chǔ)概念:
1.iteration:迭代?
2.iterable:可迭代對象 可重復(fù)迭代 滿足如下其中之一的都是iterable
可以for循環(huán):for i in iterable
可以按照index索引的對象:也就是定義了__getitem__ 方法 比如list str
定義了__iter__方法 可以隨意返回
可以調(diào)用iter(obj)的對象 并且返回一個iterator
3.iterator:迭代器對象 只能迭代next一次 需要滿足如下的迭代器協(xié)議
定義了__iter__方法 但是必須返回自身
定義了next方法,在python3.x中是__next__ 用來返回下一個值,并且當(dāng)沒有數(shù)據(jù)了,拋出StopIteration
可以保持當(dāng)前的狀態(tài)
str和list是iterable 但不是iterator
2.自定義iterator 與數(shù)據(jù)分離
自定義iterator 就是定義__iter__ 和next方法
```
class DataIter(object):
? ? def __init__(self,*args):
? ? ? ? self.data=list(args)
? ? ? ? self.ind=0
? ? def __iter__(self):
? ? ? ? return self
? ? def next(self):
? ? ? ? if self.ind==len(self.data):
? ? ? ? ? ? raise StopIteration
? ? ? ? else:
? ? ? ? ? ? data=self.data[self.ind]
? ? ? ? ? ? self.ind+=1
? ? ? ? ? ? return data
```
把iterator從數(shù)據(jù)中分離出來,分別定義一個iterable和iterator
```
class Data(object):
? ? def __init__(self,*args):
? ? ? ? self.data=list(args)
? ? def __iter__(self):#并沒有返回自身
? ? ? ? return DataIterator(self)
```
數(shù)據(jù)可以復(fù)用,因為每次返回一個DataIterator,xrange的實現(xiàn)便是這種數(shù)據(jù)和迭代分離的形式,很省內(nèi)存
為什么使用for可以迭代迭代器對象,因為for替我們做了next的活,以及接收stopIteration的處理
生成器
生成器是一種特殊的迭代器,生成器自動實現(xiàn)了“迭代器協(xié)議”(即__iter__和next方法),不需要再手動實現(xiàn)兩方法。
與生成器不同的是生成器的實現(xiàn)方式不同,可以通過生成器表達(dá)式和生成器函數(shù)兩種方式實現(xiàn),代碼更簡潔
1.包含yield的函數(shù)
生成器函數(shù)跟普通函數(shù)只有一點不一樣,就是把return換成yield,內(nèi)部實現(xiàn)了迭代器協(xié)議,同時保持狀態(tài)可以掛起
yield是數(shù)據(jù)的生產(chǎn)者,for等是數(shù)據(jù)的消費者
```
def add():
? ? ?for i in range(10):
? ? ? ? yield i
g = add()#并沒有真實執(zhí)行函數(shù),只是返回了一個生成器對象
print(g)? # <generator object add at 0x10f6110f8>
print(next(g))? # 0 真正執(zhí)行函數(shù),執(zhí)行到y(tǒng)ield一個返回值,然后就會掛起,保持當(dāng)前的名字空間等狀態(tài),然后等待下一次的調(diào)用,從yield的下一行繼續(xù)執(zhí)行
print(next(g))? # 1
```
我們可以通過yield關(guān)鍵字來定義一個生成器函數(shù),這個生成器函數(shù)返回值就是一個生成器對象;
yield可以理解為return,返回后面的值給調(diào)用者。不同的是return返回后,函數(shù)會釋放,而生成器則不會。在直接調(diào)用next方法或用for語句進(jìn)行下一次迭代時,生成器會從yield下一句開始執(zhí)行,直至遇到下一個yield。
2.生成器表達(dá)式
語法:(返回值 for 元素 in 可迭代對象 if 條件)
列表解析式的中括號換成小括號
返回一個生成器 生成器也是一個對象 屬于中間值
```
g=(i **2 for iin range(5))
print(g) #<generator object <genexpr> at 0x01167C30>
print(g.__next__()) #0
print(g.__next__()) #1
print(g.__next__()) #4
```
生成器表達(dá)式和列表解析式的區(qū)別

上下文管理器
>定義:在使用python編程中,有一個特殊的語句塊,執(zhí)行這個語句塊之前需要先執(zhí)行一些準(zhǔn)備動作,當(dāng)語句塊執(zhí)行完成后,需要繼續(xù)執(zhí)行一些收尾動作。如操作文件時,操作前打開文件,操作后關(guān)閉文件,對于這些情況,python提供了上下文管理器概念,可以通過上下文管理器來定義控制代碼塊執(zhí)行前的準(zhǔn)備動作以及執(zhí)行后的收尾動作
原理:創(chuàng)建一個上下文管理器類型的時候,就需要實現(xiàn)__enter__和__exit__方法,在python中,可以通過with語句來方便的使用上下文管理器,with語句可以在代碼塊運行前進(jìn)入一個運行時上下文(執(zhí)行__enter__方法),并在代碼塊結(jié)束后退出該上下文(執(zhí)行__exit__方法)
```
with open ("1.txt",mode='w',encoding='utf-8) as file:
? ? file.write('hello world')
```
應(yīng)用場景
文件操作、進(jìn)程線程之間互斥對象、支持上下文其他對象
自定義類實現(xiàn)
```
class Sample():
? ? def __enter__(self):
? ? ? ? return self
#exc_type:錯誤的類型? exc_val:代碼類型對應(yīng)的值 exc_tb:代碼中錯誤發(fā)生的位置
? ? def __exit__(self,exc_type,exc_val,exc_tb):
? ? ? ? print(exc_type,exc_value)
```
參數(shù)傳遞
參數(shù)傳遞類似于淺拷貝,傳遞的是值,對于不可變對象,他的引用是不可變的,所以傳值之后,相當(dāng)于新建了一個不可變對象 對于可變對象,傳遞的值,相當(dāng)于副本,改變的時候引用里的值也會發(fā)生變化
深拷貝、淺拷貝
深拷貝:copy 模塊的 deepcopy 方法,完全拷貝了父對象及其子對象,包括值與內(nèi)存地址
淺拷貝:拷貝父對象,不會拷貝對象的內(nèi)部的子對象。修改父對象的時候,不相互影響,修改子對象的時候,影響
????????????三種形式,1:切片 a=b[:]? 2:copy函數(shù) a=copy.copy(b) 3、工廠函數(shù) a=list(b)?
? ? ? ? ? ? 比如a=[1,2,3,[4,5]] b=a.copy() 修改b.append(5) a的值不會變? 修改b[3].append(6) a的值會變,因為[4,5]已經(jīng)是子對象了,未被拷貝,a和b是指向同樣的地址的
=: 引用賦值 a=b? 修改a,b也會受影響 a相當(dāng)于b的別名
is:比較兩邊的內(nèi)存地址是否相同
==:比較兩邊的值是否相等
內(nèi)存管理
三個方面:1、對象的引用計數(shù)機(jī)制,2、垃圾回收機(jī)制,3、內(nèi)存池機(jī)制
1、對象引用計數(shù)機(jī)制
python使用計數(shù)機(jī)制,來追蹤內(nèi)存中的對象,所有對象都要引用計數(shù)
引用計數(shù)增加的情況
1:一個對象分配一個新的名稱
2:將其放入一個容器中,如列表、元組、字典
引用計數(shù)減少的情況
1:使用del語句對對象別名顯示的銷毀
2:引用超出作用域或被重新賦值
對于不可變的數(shù)據(jù)類型,如字符串,數(shù)字,解釋器會在程序中的不同部分共享內(nèi)存,以便簡約內(nèi)存
2、垃圾回收機(jī)制
1:當(dāng)一個對象的引用計數(shù)歸零的時候,它將被垃圾收集機(jī)制處理掉
2:當(dāng)兩個對象a和b相互引用的時候,del語句可以減少a b的引用計數(shù),并銷毀用于引用底層對象的名稱,然而由于每個對象都包含一個對其他對象的引用,因此引用計數(shù)不會歸零,對象也不會銷毀。(從而導(dǎo)致內(nèi)存泄露)。為解決這一問題,解釋器會定期執(zhí)行一個循環(huán)檢測器,搜索不可訪問對象的循環(huán)并刪除它們。
3、內(nèi)存池機(jī)制
Python提供了對內(nèi)存的垃圾收集機(jī)制,但是它將不用的內(nèi)存放到內(nèi)存池而不是返回給操作系統(tǒng)。
1,Pymalloc機(jī)制。為了加速Python的執(zhí)行效率,Python引入了一個內(nèi)存池機(jī)制,用于管理對小塊內(nèi)存的申請和釋放。
2,Python中所有小于256個字節(jié)的對象都使用pymalloc實現(xiàn)的分配器,而大的對象則使用系統(tǒng)的malloc。
3,對于Python對象,如整數(shù),浮點數(shù)和List,都有其獨立的私有內(nèi)存池,對象間不共享他們的內(nèi)存池。也就是說如果你分配又釋放了大量的整數(shù),用于緩存這些整數(shù)的內(nèi)存就不能再分配給浮點數(shù)。
內(nèi)存泄露
如果存在循環(huán)引用,并且被循環(huán)引用的對象定義了__del__方法,就會發(fā)生內(nèi)存泄露,對象定義了__del__方法,這些對象變?yōu)閡ncollectable,垃圾回收機(jī)制無法收集這些對象
創(chuàng)建對象后,Python解釋器默認(rèn)調(diào)用__init__()方法。
當(dāng)刪除一個對象時,Python解釋器也會默認(rèn)調(diào)用一個方法,這個方法為__del__()方法,手動調(diào)用del還是由Python自動回收都會觸發(fā)__del__方法執(zhí)行。
當(dāng)使用del刪除變量指向的對象時,如果對象的引用計數(shù)不會1,比如3,那么此時只會讓這個引用計數(shù)減1,即變?yōu)?,當(dāng)再次調(diào)用del時,變?yōu)?,如果再調(diào)用1次del,此時會真的把對象進(jìn)行刪除,
但是del xxx?不會主動調(diào)用__del__方法,只有引用計數(shù) == 0時,__del__()才會被執(zhí)行,并且定義了__del_()的實例無法被Python的循環(huán)垃圾收集器收集,所以盡量不要自定義__del__()。一般情況下,__del__()?不會破壞垃圾處理器。
python2和python3的區(qū)別
? ?1、Python3 使用 print 必須要以小括號包裹打印內(nèi)容,比如 print('hi')
? ? ? ?Python2 既可以使用帶小括號的方式,也可以使用一個空格來分隔打印內(nèi)容,比? ? ? ? 如 print 'hi'
? ? 2、python2 range(1,10)返回列表,python3中返回迭代器,節(jié)約內(nèi)存
? ? 3、python2中使用ascii編碼,python中使用utf-8編碼
? ? 4、python2中unicode表示字符串序列,str表示字節(jié)序列
? ? ? python3中str表示字符串序列,byte表示字節(jié)序列
多態(tài)
作用:讓具有不同功能的函數(shù)可以使用相同的函數(shù)名,這樣就可以用一個函數(shù)名調(diào)用不同內(nèi)容(功能)的函數(shù)。
特點:
1、只關(guān)心對象的實例方法是否同名,不關(guān)心對象所屬的類型;
2、對象所屬的類之間,繼承關(guān)系可有可無;
3、多態(tài)的好處可以增加代碼的外部調(diào)用靈活度,讓代碼更加通用,兼容性比較強(qiáng);
4、多態(tài)是調(diào)用方法的技巧,不會影響到類的內(nèi)部設(shè)計。
字典的實現(xiàn)原理
python中的字典底層依靠哈希表(hash table)實現(xiàn)
哈希表是key-value類型的數(shù)據(jù)結(jié)構(gòu), 可以理解為一個鍵值需要按照一定規(guī)則存放的數(shù)組, 而哈希函數(shù)就是這個規(guī)則
字典本質(zhì)上是一個散列表(總有空白元素的數(shù)組, python至少保證1/3的數(shù)組是空的), 字典中的每個鍵都占用一個單元, 一個單元分為兩部分, 分別是對鍵的引用和對值的引用, 使用hash函數(shù)獲得鍵的散列值, 散列值對數(shù)組長度取余, 取得的值就是存放位置的索引
哈希沖突(數(shù)組的索引相同), 使用開放尋址法解決
由于哈希算法被計算的數(shù)據(jù)是無限的,而計算后的結(jié)果范圍有限,因此總會存在不同的數(shù)據(jù)經(jīng)過計算后得到的值相同,這就是哈希沖突。
從發(fā)生沖突的那個單元起,按照一定的次序,從哈希表中找到一個空閑的單元。然后把發(fā)生沖突的元素存入到該單元的一種方法。開放定址法需要的表長度要大于等于所需要存放的元素。
JSON和字典的區(qū)別
json是一種數(shù)據(jù)格式,是純字符串
dict是一個完整的數(shù)據(jù)結(jié)構(gòu)
json的key可以是有序、重復(fù)的;dict的key不可以重復(fù)
json的value只能是字符串、浮點數(shù)、布爾值或者null,或者它們構(gòu)成的數(shù)組或者對象。
json任意key存在默認(rèn)值undefined,dict默認(rèn)沒有默認(rèn)值
格式就會有一些形式上的限制,比如json的格式要求必須且只能使用雙引號作為key或者值的邊界符號(值如果是數(shù)字可以不用加雙引號),不能使用單引號,用單引號或者不用引號會導(dǎo)致讀取數(shù)據(jù)錯誤,而且“key”必須使用邊界符(雙引號),但字典就無所謂了,可以使用單引號,也可以使用雙引號。
重載和重寫
答:重載是指函數(shù)名相同,參數(shù)列表不同的函數(shù)實現(xiàn)方法。它們的返回值可以不同,但返回值不可以作為區(qū)分不同重載函數(shù)的標(biāo)志。
重寫是指函數(shù)名相同,參數(shù)列表相同,只有方法體不同的實現(xiàn)方法,即函數(shù)花括號里面不一樣,一般用于子類繼承父類時對父類方法的重寫,父類函數(shù)中必須要有virtual關(guān)鍵字。(子類的同名方法屏蔽了父類方法的現(xiàn)象稱為隱藏。
python多線程
1.線程概念:
線程是指進(jìn)程內(nèi)的一個執(zhí)行單元,也是進(jìn)程內(nèi)的可調(diào)度實體.
與進(jìn)程的區(qū)別:
(1) 地址空間:進(jìn)程內(nèi)的一個執(zhí)行單元;進(jìn)程至少有一個線程;它們共享進(jìn)程的地址空間;而進(jìn)程有自己獨立的地址空間;
(2) 資源擁有:進(jìn)程是資源分配和擁有的單位,同一個進(jìn)程內(nèi)的線程共享進(jìn)程的資源
(3) 線程是處理器調(diào)度的基本單位,但進(jìn)程不是.
(4) 二者均可并發(fā)執(zhí)行.
簡而言之,一個程序至少有一個進(jìn)程,一個進(jìn)程至少有一個線程.
線程的劃分尺度小于進(jìn)程,使得多線程程序的并發(fā)性高。
另外,進(jìn)程在執(zhí)行過程中擁有獨立的內(nèi)存單元,而多個線程共享內(nèi)存,從而極大地提高了程序的運行效率。
2.線程和進(jìn)程間的區(qū)別
進(jìn)程就是一個應(yīng)用程序在處理機(jī)上的一次執(zhí)行過程,它是一個動態(tài)的概念,而線程是進(jìn)程中的一部分,進(jìn)程包含多個線程在運行。
多線程可以共享全局變量,多進(jìn)程不能。多線程中,所有子線程的進(jìn)程號相同;多進(jìn)程中,不同的子進(jìn)程進(jìn)程號不同。
進(jìn)程是具有一定獨立功能的程序關(guān)于某個數(shù)據(jù)集合上的一次運行活動,進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個獨立單位.
線程是進(jìn)程的一個實體,是CPU調(diào)度和分派的基本單位,它是比進(jìn)程更小的能獨立運行的基本單位.線程自己基本上不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源(如程序計數(shù)器,一組寄存器和棧),但是它可與同屬一個進(jìn)程的其他的線程共享進(jìn)程所擁有的全部資源.
一個線程可以創(chuàng)建和撤銷另一個線程;同一個進(jìn)程中的多個線程之間可以并發(fā)執(zhí)行.
3.python線程模塊
?python主要是通過thread和threading這兩個模塊來實現(xiàn)多線程支持。
python的thread模塊是比較底層的模塊,python的threading模塊是對thread做了一些封裝,可以更加方便的被使用。
但是python(cpython)由于GIL的存在無法使用threading充分利用CPU資源,如果想充分發(fā)揮多核CPU的計算能力需要使用multiprocessing模塊(Windows下使用會有諸多問題)。
3.1創(chuàng)建線程
?python3.x中通過threading模塊創(chuàng)建新的線程有兩種方法:
一種是通過threading.Thread(Target=executable Method)-即傳遞給Thread對象一個可執(zhí)行方法(或?qū)ο螅?/p>

第二種是繼承threading.Thread定義子類并重寫run()方法。第二種方法中,唯一必須重寫的方法是run()

3.2線程同步
線程執(zhí)行是亂序的,要使之有序,需要進(jìn)行線程同步
如果多個線程共同對某個數(shù)據(jù)修改,則可能出現(xiàn)不可預(yù)料的結(jié)果,為了保證數(shù)據(jù)的正確性,需要對多個線程進(jìn)行同步。
使用Thread對象的Lock和Rlock可以實現(xiàn)簡單的線程同步,這兩個對象都有acquire方法和release方法,對于那些需要每次只允許一個線程操作的數(shù)據(jù),可以將其操作放到acquire和release方法之間。
需要注意的是,Python有一個GIL(Global Interpreter Lock)機(jī)制,任何線程在運行之前必須獲取這個全局鎖才能執(zhí)行,每當(dāng)執(zhí)行完100條字節(jié)碼,全局鎖才會釋放,切換到其他線程執(zhí)行。
多線程實現(xiàn)同步有四種方式:鎖機(jī)制,信號量,條件判斷和同步隊列。
3.2.1鎖機(jī)制
threading的Lock類,用該類的acquire函數(shù)進(jìn)行加鎖,用realease函數(shù)進(jìn)行解鎖

3.2.2線程同步隊列queue
Python的queue模塊中提供了同步的、線程安全的隊列類,包括FIFO(先入先出)隊列Queue,LIFO(后入先出)隊列LifoQueue,和優(yōu)先級隊列PriorityQueue。這些隊列都實現(xiàn)了鎖原語,能夠在多線程中直接使用??梢允褂藐犃衼韺崿F(xiàn)線程間的同步。
queue模塊中的常用方法:
queue.qsize() 返回隊列的大小
queue.empty() 如果隊列為空,返回True,反之False
queue.full() 如果隊列滿了,返回True,反之False
queue.full 與 maxsize 大小對應(yīng)
queue.get([block[, timeout]])獲取隊列,timeout等待時間
queue.get_nowait() 相當(dāng)Queue.get(False)
queue.put(item) 寫入隊列,timeout等待時間
queue.put_nowait(item) 相當(dāng)Queue.put(item, False)
queue.task_done() 在完成一項工作之后,Queue.task_done()函數(shù)向任務(wù)已經(jīng)完成的隊列發(fā)送一個信號
queue.join() 實際上意味著等到隊列為空,再執(zhí)行別的操作

3.3 線程池
我們把任務(wù)放進(jìn)隊列中去,然后開N個線程,每個線程都去隊列中取一個任務(wù),執(zhí)行完了之后告訴系統(tǒng)說我執(zhí)行完了,然后接著去隊列中取下一個任務(wù),直至隊列中所有任務(wù)取空,退出線程。
使用線程池:
由于線程預(yù)先被創(chuàng)建并放入線程池中,同時處理完當(dāng)前任務(wù)之后并不銷毀而是被安排處理下一個任務(wù),因此能夠避免多次創(chuàng)建線程,從而節(jié)省線程創(chuàng)建和銷毀的開銷,能帶來更好的性能和系統(tǒng)穩(wěn)定性。
服務(wù)器CPU核數(shù)有限,能夠同時并發(fā)的線程數(shù)有限,并不是開得越多越好,以及線程切換是有開銷的,如果線程切換過于頻繁,反而會使性能降低
線程執(zhí)行過程中,計算時間分為兩部分:
CPU計算,占用CPU
不需要CPU計算,不占用CPU,等待IO返回,比如recv(), accept(), sleep()等操作,具體操作就是比如
訪問cache、RPC調(diào)用下游service、訪問DB,等需要網(wǎng)絡(luò)調(diào)用的操作
https://blog.csdn.net/daiyu__zz/article/details/81912018
在Python中如何實現(xiàn)多線程?
一個線程就是一個輕量級進(jìn)程,多線程能讓我們一次執(zhí)行多個線程。我們都知道,Python是多線程語言,其內(nèi)置有多線程工具包。
Python中的GIL(全局解釋器鎖)確保一次執(zhí)行單個線程。一個線程保存GIL并在將其傳遞給下個線程之前執(zhí)行一些操作,這會讓我們產(chǎn)生并行運行的錯覺。但實際上,只是線程在CPU上輪流運行。當(dāng)然,所有的傳遞會增加程序執(zhí)行的內(nèi)存壓力。
多進(jìn)程
通過multiprocessing 實現(xiàn)多進(jìn)程
```
from multiprocessingimport Process
import time,random
def Test(name):
print("welcome to my house %s" % name)
time.sleep(random.randint(1,3))
print("see you next time %s" % name)
if __name__ =='__main__':
p1 = Process(target=Test,args=('鳴人',))
p2 = Process(target=Test,args=('佐助',))
p3 = Process(target=Test,args=('小櫻',))
p1.start()
p2.start()
```

python數(shù)據(jù)庫處理

https://www.liaoxuefeng.com/wiki/1016959663602400/1017803857459008
python常用方法
a[::-1]和a[i:j]
https://blog.csdn.net/mingyuli/article/details/81604795
b = a[i:j] ? 表示復(fù)制a[i]到a[j-1],以生成新的list對象
a = [0,1,2,3,4,5,6,7,8,9]
b = a[1:3] ? #?[1,2]
b = a[i:j:s]表示:i,j與上面的一樣,但s表示步進(jìn),缺省為1.
所以a[i:j:1]相當(dāng)于a[i:j]
當(dāng)s<0時,i缺省時,默認(rèn)為-1. j缺省時,默認(rèn)為-len(a)-1
所以a[::-1]相當(dāng)于 a[-1:-len(a)-1:-1],也就是從最后一個元素到第一個元素復(fù)制一遍,即倒序。
a='python'
b=a[::-1]
print(b) #nohtyp
c=a[::-2]
print(c) #nhy
#從后往前數(shù)的話,最后一個位置為-1
d=a[:-1]? #從位置0到位置-1之前的數(shù)
print(d)? #pytho
e=a[:-2]? #從位置0到位置-2之前的數(shù)
print(e)? #pyth
reverse
a = [1,2,3]
a.reverse()?
a=[3,2,1]
返回值為NA,作用于自身
list
當(dāng)數(shù)組不為空時:
if len(list_temp)
if list_temp:
字符串操作
https://www.cnblogs.com/yaxin1989/p/6129188.html
join
l1=['a','b','c','d']
s1=''.join(l1)? ? abcd
s2='a'.join(l1)? aabacada
s3='4'.join(l1) a4b4c4d4
split
s2.split('a')? ['a','b','c','d']
s3.split('4')?['a','b','c','d']
strip??
lstrip rstrip 去掉字符串兩端字符,默認(rèn)空格
s='222abc22222'
s.strip('2')? 'abc'
s.lstrip('2') 'abc22222'
s.rstrip('2') '222abc'
bin函數(shù)
https://www.runoob.com/python/python-func-bin.html
判斷二進(jìn)制中有多少個1
bin(n).count('1')#將n轉(zhuǎn)換成二進(jìn)制,然后數(shù)里面的1的個數(shù)
format(n,'b') #將n轉(zhuǎn)換成二進(jìn)制
判斷是否是數(shù)字、字母
str1="123"
str2="ABC"
str3="1AB"
str1.isdigit()#判斷是否是數(shù)字
str2.isalpha()#判斷是否是字母
str3.isalnum()#判斷是否是字母和數(shù)字組合
python的次方
10的2次方 10**2?
import math
math.pow(10,2)
2**31表示2的31次冪