溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python中不常見的冷門知識有哪些

發(fā)布時間:2020-08-07 09:21:06 來源:億速云 閱讀:212 作者:小新 欄目:編程語言

這篇文章主要介紹Python中不常見的冷門知識有哪些,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

下面時Python中一些不常見的冷門知識,感興趣的小伙伴不妨來學習一下。

1、省略號也是對象

… 這是省略號,在Python中,一切皆對象。它也不例外。在 Python 中,它叫做 Ellipsis 。在 Python 3 中你可以直接寫…來得到這玩意。

>>> ...

Ellipsis

>>> type(...)

<class 'ellipsis'>

而在 Python2 中沒有…這個語法,只能直接寫Ellipsis來獲取。

>>> Ellipsis

Ellipsis

>>> type(Ellipsis)

<type 'ellipsis'>

它轉為布爾值時為真

>>> bool(...)

True

最后,這東西是一個單例。

>>> id(...)

4362672336

>>> id(...)

4362672336

這東西有啥用呢?據(jù)說它是Numpy的語法糖,不玩 Numpy 的人,可以說是沒啥用的。

在網上只看到這個 用 … 代替 pass ,稍微有點用,但又不是必須使用的。

try:

    1/0

except ZeroDivisionError:

    ...

2、增量賦值的性能更好

諸如 += 和 *= 這些運算符,叫做 增量賦值運算符。這里使用用 += 舉例,以下兩種寫法,在效果上是等價的。

# 第一種

a = 1 ; a += 1

# 第二種

a = 1; a = a + 1

+= 其背后使用的魔法方法是 iadd,如果沒有實現(xiàn)這個方法則會退而求其次,使用 add 。

這兩種寫法有什么區(qū)別呢?

用列表舉例 a += b,使用 add 的話就像是使用了a.extend(b),如果使用 add 的話,則是 a = a+b,前者是直接在原列表上進行擴展,而后者是先從原列表中取出值,在一個新的列表中進行擴展,然后再將新的列表對象返回給變量,顯然后者的消耗要大些。

所以在能使用增量賦值的時候盡量使用它。

3、and 和or 的取值順序

and 和 or 是我們再熟悉不過的兩個邏輯運算符。而我們通常只用它來做判斷,很少用它來取值。

如果一個or表達式中所有值都為真,Python會選擇第一個值,而and表達式則會選擇第二個。

>>>(2 or 3) * (5 and 7)

14  # 2*7

4、修改解釋器提示符

>>> import sys                      

>>> sys.ps1                         

'>>> '                              

>>> sys.ps2                         

'... '                              

>>>                                 

>>> sys.ps2 = '---------------- '                 

>>> sys.ps1 = 'Python編程時光>>>'       

Python編程時光>>>for i in range(2):     

----------------    print (i)                    

----------------                                 

5、默認參數(shù)最好不為可變對象

函數(shù)的參數(shù)分三種

可變參數(shù)

默認參數(shù)

關鍵字參數(shù)

今天要說的是,傳遞默認參數(shù)時,新手很容易踩雷的一個坑。

先來看一個示例:

def func(item, item_list=[]):

    item_list.append(item)

    print(item_list)

func('iphone')

func('xiaomi', item_list=['oppo','vivo'])

func('huawei')

在這里,你可以暫停一下,思考一下會輸出什么?

思考過后,你的答案是否和下面的一致呢

['iphone']

['oppo', 'vivo', 'xiaomi']

['iphone', 'huawei']

如果是,那你可以跳過這部分內容,如果不是,請接著往下看,這里來分析一下。

Python 中的 def 語句在每次執(zhí)行的時候都初始化一個函數(shù)對象,這個函數(shù)對象就是我們要調用的函數(shù),可以把它當成一個一般的對象,只不過這個對象擁有一個可執(zhí)行的方法和部分屬性。

對于參數(shù)中提供了初始值的參數(shù),由于 Python 中的函數(shù)參數(shù)傳遞的是對象,也可以認為是傳地址,在第一次初始化 def 的時候,會先生成這個可變對象的內存地址,然后將這個默認參數(shù) item_list 會與這個內存地址綁定。在后面的函數(shù)調用中,如果調用方指定了新的默認值,就會將原來的默認值覆蓋。如果調用方沒有指定新的默認值,那就會使用原來的默認值。

在這里插入圖片描述

6、訪問類中的私有方法

大家都知道,類中可供直接調用的方法,只有公有方法(protected類型的方法也可以,但是不建議)。也就是說,類的私有方法是無法直接調用的。

這里先看一下例子

class Kls():

    def public(self):

        print('Hello public world!')

    def __private(self):

        print('Hello private world!')

    def call_private(self):

        self.__private()

ins = Kls()

# 調用公有方法,沒問題

ins.public()

# 直接調用私有方法,不行

ins.__private()

# 但你可以通過內部公有方法,進行代理

ins.call_private()

既然都是方法,那我們真的沒有方法可以直接調用嗎?

當然有啦,只是建議你千萬不要這樣弄,這里只是普及,讓你了解一下。

# 調用私有方法,以下兩種等價

ins._Kls__private()

ins.call_private()

7、時有時無的切片異常

這是個簡單例子

my_list = [1, 2, 3, 4, 5]

print(my_list[5])

Traceback (most recent call last):

  File "F:/Python Script/test.py", line 2, in <module>

    print(my_list[5])

IndexError: list index out of range

來看看,如下這種寫法就不會報索引異常,執(zhí)行my_list[5:],會返回一個新list:[]。

my_list = [1, 2, 3]

print(my_list[5:])

8、for 死循環(huán)

for 循環(huán)可以說是 基礎得不能再基礎的知識點了。但是如果讓你用 for 寫一個死循環(huán),你會寫嗎?(問題來自群友 陳**)

這是個開放性的問題,在往下看之前,建議你先嘗試自己思考,你會如何解答。

好了,如果你還沒有思路,那就來看一下 一個海外 MIT 群友的回答:

for i in iter(int, 1):pass

是不是懵逼了。iter 還有這種用法?這為啥是個死循環(huán)?

這真的是個冷知識,關于這個知識點,你如果看中文網站,可能找不到相關資料。

還好你可以通過 IDE 看py源碼里的注釋內容,介紹了很詳細的使用方法。

原來iter有兩種使用方法,通常我們的認知是第一種,將一個列表轉化為一個迭代器。

而第二種方法,他接收一個 callable對象,和一個sentinel 參數(shù)。第一個對象會一直運行,直到它返回 sentinel 值才結束。

在這里插入圖片描述

那int 呢,這又是一個知識點,int 是一個內建方法。通過看注釋,可以看出它是有默認值0的。你可以在終端上輸入 int() 看看是不是返回0。

在這里插入圖片描述

由于int() 永遠返回0,永遠返回不了1,所以這個 for 循環(huán)會沒有終點。一直運行下去。

9、奇怪的字符串

字符串類型作為 Python 中最常用的數(shù)據(jù)類型之一,Python解釋器為了提高字符串使用的效率和使用性能,做了很多優(yōu)化。

例如:Python 解釋器中使用了 intern(字符串駐留)的技術來提高字符串效率。

什么是 intern 機制?就是同樣的字符串對象僅僅會保存一份,放在一個字符串儲蓄池中,是共用的,當然,肯定不能改變,這也決定了字符串必須是不可變對象。

示例一

# Python2.7

>>> a = "Hello_Python"

>>> id(a)

32045616

>>> id("Hello" + "_" + "Python")

32045616

# Python3.7

>>> a = "Hello_Python"

>>> id(a)

38764272

>>> id("Hello" + "_" + "Python")

32045616

示例二

>>> a = "MING"

>>> b = "MING"

>>> a is b

True

# Python2.7

>>> a, b = "MING!", "MING!"

>>> a is b

True

# Python3.7

>>> a, b = "MING!", "MING!"

>>> a is b

False

示例三

# Python2.7

>>> 'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'

True

>>> 'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'

False

# Python3.7

>>> 'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'

True

>>> 'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'

True

示例四

>>> s1="hello"

>>> s2="hello"

>>> s1 is s2

True

# 如果有空格,默認不啟用intern機制

>>> s1="hell o"

>>> s2="hell o"

>>> s1 is s2

False

# 如果一個字符串長度超過20個字符,不啟動intern機制

>>> s1 = "a" * 20

>>> s2 = "a" * 20

>>> s1 is s2

True

>>> s1 = "a" * 21

>>> s2 = "a" * 21

>>> s1 is s2

False

>>> s1 = "ab" * 10

>>> s2 = "ab" * 10

>>> s1 is s2

True

>>> s1 = "ab" * 11

>>> s2 = "ab" * 11

>>> s1 is s2

False

10、兩次return

我們都知道,try…finally… 語句的用法,不管 try 里面是正常執(zhí)行還是報異常,最終都能保證finally能夠執(zhí)行。

同時,我們又知道,一個函數(shù)里只要遇到 return 函數(shù)就會立馬結束。

基于以上這兩點,我們來看看這個例子,到底運行過程是怎么樣的?

>>> def func():

...     try:

...         return 'try'

...     finally:

...         return 'finally'

...

>>> func()

'finally'

驚奇的發(fā)現(xiàn),在try里的return居然不起作用。

原因是,在try…finally…語句中,try中的return會被直接忽視,因為要保證finally能夠執(zhí)行。

以上是Python中不常見的冷門知識有哪些的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI