成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Python 為什么要在 18 年前引入布爾類型?且與 C、C++ 和 Java 都不同?

新聞 前端
本篇文章是我剛翻譯的 PEP-285,作者是 Python 之父 Guido van Rossum。這個(gè) PEP 意義非常重大,Python 的 bool 類型就是從它開始引入的,而我在上篇文章中分析到的很多問題,都能在這篇十幾年前的文檔中找到解釋!

 [[337505]]

本篇文章是我剛翻譯的 PEP-285,作者是 Python 之父 Guido van Rossum。這個(gè) PEP 意義非常重大,Python 的 bool 類型就是從它開始引入的,而我在上篇文章中分析到的很多問題,都能在這篇十幾年前的文檔中找到解釋!另外它還回應(yīng)了比較典型的一些爭議,值得大家了解下。

PEP原文 : https://www.python.org/dev/peps/pep-0285

PEP標(biāo)題: PEP 285 -- Adding a bool type

PEP作者:Guido van Rossum

創(chuàng)建日期:2002-03-08

合入版本:2.3

譯者: 豌豆花下貓@Python貓公眾號(hào)

PEP翻譯計(jì)劃: https://github.com/chinesehuazhou/peps-cn

概要

本 PEP 提議引入一個(gè)新的內(nèi)置類型 bool ,它將包含兩個(gè)常量 False 和 True 。這個(gè) bool 類型是 int 類型的直接子類型(在 C 中),并且在除了 repr() 和 str() 之外的大多數(shù)方面,它的值 False 和 True 都將表現(xiàn)得像是 0 和 1(例如,F(xiàn)alse == 0 和 True == 1 都為真)。

所有在概念上需返回布爾結(jié)果的內(nèi)置操作,都將更改為返回 False 或 True,而不再是 0 或 1,例如,比較操作、“not”運(yùn)算和 isinstance() 之類的斷言方法。

評(píng)審

我已經(jīng)收集了太多太多的反饋意見,因此我宣布:評(píng)審階段(review period)正式 結(jié)束。 我今天吃的是中國菜,我的簽語餅上寫著:“Strong and bitter words indicate a weak cause.” 它使我想起了一些反對(duì)本 PEP 的帖子... :-)

(譯注:1、簽語餅即 fortune cookies,這是一種美國文化特色。美國的中餐館在結(jié)賬的時(shí)候流行給客人一些寫了簽語的餅干,一般都是祝福語。2、那句簽語出自維克多·雨果,意為:理虧者言辭激烈)

無論如何,這些是我的 BDFL 聲明。(執(zhí)行摘要(Executive summary):我不會(huì)更改任何內(nèi)容;所有其它提議都會(huì)被拒絕。)

1、本 PEP 應(yīng)該被接受嗎?

=>是的。

有很多反對(duì)本 PEP 的觀點(diǎn)。其中多數(shù)是出于誤解。我已嘗試在下面的 PEP 正文中澄清一些最常見的誤解。對(duì)我而言唯一值得考慮的問題是新手們傾向于寫“ if x == True”,但“if x”就足夠了。下面也有更多關(guān)于它的信息。我認(rèn)為這不足以拒絕本 PEP。

2、 str(True) 應(yīng)該返回“True”還是“1”?“1”可能會(huì)減少向后兼容性問題,但看起來很奇怪。( repr(True) 將始終返回“True”。)

=>“True”。

幾乎所有評(píng)審人都同意這一點(diǎn)。

3、常量應(yīng)該被命名為“True”和“False”(類似于 None)還是“true”和“false”(像 C++、Java 和 C99 那樣)?

=>True 和 False。

大多數(shù)評(píng)審人都認(rèn)為 Python 內(nèi)的一致性要比跟其它語言的一致性更為重要。

4、是否應(yīng)該通過適當(dāng)?shù)母婢瘉硐龑?duì)布爾值的非布爾運(yùn)算,以便例如 True + 1 最終(在 Python 3000 中)變?yōu)榉欠ǖ模?/h4>

=>不該

有一小部分觀點(diǎn)響亮的人,希望看到“教科書式”的布爾類型,即完全不支持算術(shù)運(yùn)算,但大多數(shù)評(píng)審人都同意我,認(rèn)為布爾類型應(yīng)該支持算術(shù)運(yùn)算。

5、 operator.truth(x) 應(yīng)該返回 int 還是 bool?

=>bool。

Tim Peters 認(rèn)為應(yīng)該返回一個(gè)整數(shù),但是幾乎所有其他評(píng)審人都認(rèn)為應(yīng)該返回一個(gè)布爾值。我的理由:operator.truth() 意味著強(qiáng)制其參數(shù)使用布爾類型上下文(它調(diào)用 C API PyObject_IsTrue() )。無論結(jié)果是 int 還是 bool,都是次要的;如果有 bool,則沒有理由不使用它。(在本 PEP 下,operator.truth() 成為了 bool() 的別名;這也可以。)

6、bool 應(yīng)該繼承自 int 嗎?

=>是的。

在理想的情況下,bool 最好是實(shí)現(xiàn)為一種單獨(dú)的整數(shù)類型,且支持執(zhí)行混合的算術(shù)操作。但是,從 int 繼承出 bool 將極大地簡化實(shí)現(xiàn)(部分原因是,所有調(diào)用 PyInt_Check() 的 C 代碼都可兼容——它對(duì)于 int 的子類會(huì)返回 true)。

另外,我認(rèn)為這符合可替換性(substitutability)概念:代碼中需要 int 時(shí),可以喂入 bool,它等同于 0 或 1。代碼中需要 bool 時(shí),若賦予 int,則可能不符合預(yù)期;例如,3&4 計(jì)算為 0,但是當(dāng) 3 和 4 被視為真值時(shí),卻都為真。

7、是否應(yīng)該改變“bool”的叫法?

=>不。

一些評(píng)審人主張使用 boolean  而不是 bool,因?yàn)檫@樣更容易理解(新手可能聽說過布爾代數(shù)(Boolean algebra),但可能對(duì) bool 無感),或者因?yàn)樗麄冇憛捒s寫。

我的觀點(diǎn):Python 明智地運(yùn)用縮寫(例如'def'、'int'、'dict'),我不認(rèn)為這會(huì)造成理解的負(fù)擔(dān)。對(duì)于新手來說,無論它被叫作 waffle 還是 bool 都沒關(guān)系;這只是一個(gè)新詞,他們很快就能掌握它的含義。

(譯注:waffle,我們一般熟知的意思是“華夫餅干”,但它還有個(gè)意思是“無意義的、無關(guān)緊要的、胡亂的話”)

一位評(píng)審人認(rèn)為可以叫“truth”。我覺得這個(gè)叫法沒有吸引力,實(shí)際上更傾向于保留該術(shù)語(在文檔中),以指代在 Python 中已經(jīng)存在的具體的真值概念。例如:“當(dāng)將一個(gè)容器解釋為一個(gè) truth 值時(shí),空容器會(huì)被視為假,而非空容器則被視為真”。

8、將來是否應(yīng)該要求布爾運(yùn)算符(例如“if”、“and”和“not”)使用一個(gè)布爾值作為參數(shù),例如令“if []:”變?yōu)榉欠ǖ模蟊仨殞懗?ldquo; if bool([]):” ???

=>不!??!

有些人認(rèn)為,這就是一門有教科書式布爾類型的語言應(yīng)該的做法。因?yàn)樗惶崞鹆?,所以其他人?dān)心我可能會(huì)同意這一做法。

我來明確闡述對(duì)此的立場:這不是本 PEP 的動(dòng)機(jī),我也無意進(jìn)行更改。(另請(qǐng)參見下面的“澄清”部分。)

基本原理

大多數(shù)語言最終都會(huì)發(fā)展出一個(gè)布爾類型,甚至 C99(新的改進(jìn)版 C 標(biāo)準(zhǔn),尚未廣泛采用)也有一個(gè)。 (譯注:C99 標(biāo)準(zhǔn)誕生于 1999 年,本 PEP 寫于 2002 年,時(shí)過境遷,如今 C99 標(biāo)準(zhǔn)基本上已是落伍的了)

許多程序員都覺得需要一種布爾類型,大多數(shù) Python 文檔因缺少布爾類型而含有歉意。我看過很多模塊,它們?cè)陧敳慷x了常量“False = 0”和“True = 1”(或類似的常量),并使用它們。

問題是每個(gè)人的做法都不一樣。例如,你應(yīng)該使用“FALSE”、“false”、“False”、“F”還是“f”呢?另外,假值應(yīng)該為 0 或 None,或是一個(gè)其它的布爾類型打印出“true”或“false”呢?在語言中添加一個(gè)標(biāo)準(zhǔn)的布爾類型可以解決這些問題。

一些外部庫(例如數(shù)據(jù)庫和 RPC 相關(guān)的包)需要能夠區(qū)分布爾值和整數(shù)值,盡管通??梢灾贫ǔ鼋鉀Q方案,但如果語言本身提供了標(biāo)準(zhǔn)的布爾類型,則會(huì)更容易。這也適用于 Jython:某些 Java 類具有分別用于 int 和 boolean 參數(shù)的重載方法或構(gòu)造函數(shù)。布爾類型可用于選擇布爾變量。(顯然,某些 COM 接口也是如此。)

標(biāo)準(zhǔn)的布爾類型(bool type)也可以作為強(qiáng)制將值解釋為布爾值(Boolean)的方法,該方法可用于標(biāo)準(zhǔn)化布爾值。當(dāng)一個(gè)布爾值需要?dú)w一化為兩個(gè)值之一時(shí),bool(x) 比“not not x”更清晰,也比這種寫法更簡潔:

  1. if x: 
  2.  
  3. return 1 
  4.  
  5. else
  6.  
  7. return 0 

這是從傳授 Python 中得出的一些經(jīng)驗(yàn)。當(dāng)向人們?cè)诮换ナ浇K端中展示比較運(yùn)算符時(shí),我認(rèn)為這有點(diǎn)難看:

  1. >>> a = 13 
  2.  
  3. >>> b = 12 
  4.  
  5. >>> a > b 
  6.  
  7. 1 
  8.  
  9. >>> 

如果是這樣的話:

  1. >>> a > b 
  2.  
  3. True 
  4.  
  5. >>> 

每次會(huì)少花一毫秒的時(shí)間思考打印出的 0 或 1。

還有一個(gè)問題(它甚至困擾了曾經(jīng)經(jīng)驗(yàn)豐富但遠(yuǎn)離了 Python 一段時(shí)間的人):

  1. >>> cmp(a, b) 
  2.  
  3. 1 
  4.  
  5. >>> cmp(a, a) 
  6.  
  7. 0 
  8.  
  9. >>> 

你可能會(huì)傾向于認(rèn)為 cmp() 也返回一個(gè)布爾值,但實(shí)際上它可以返回三個(gè)不同的值(-1、0、1)。如果整數(shù)沒有(通常)被用于表示布爾值結(jié)果,則這可以更加明顯地表達(dá)出其它的含義。(譯注:即只用 True/False 表示布爾值,則整數(shù)表達(dá)其它含義時(shí)就不會(huì)有歧義)

規(guī)范

以下 Python 代碼詳細(xì)列舉了新類型的大多數(shù)屬性:

  1. class bool(int): 
  2.  
  3.  
  4. def __new__(cls, val=0): 
  5.  
  6. # This constructor always returns an existing instance 
  7.  
  8. if val: 
  9.  
  10. return True 
  11.  
  12. else
  13.  
  14. return False 
  15.  
  16.  
  17. def __repr__(self): 
  18.  
  19. if self
  20.  
  21. return "True" 
  22.  
  23. else
  24.  
  25. return "False" 
  26.  
  27.  
  28. __str__ = __repr__ 
  29.  
  30.  
  31. def __and__(self, other): 
  32.  
  33. if isinstance(other, bool): 
  34.  
  35. return bool(int(self) & int(other)) 
  36.  
  37. else
  38.  
  39. return int.__and__(self, other) 
  40.  
  41.  
  42. __rand__ = __and__ 
  43.  
  44.  
  45. def __or__(self, other): 
  46.  
  47. if isinstance(other, bool): 
  48.  
  49. return bool(int(self) | int(other)) 
  50.  
  51. else
  52.  
  53. return int.__or__(self, other) 
  54.  
  55.  
  56. __ror__ = __or__ 
  57.  
  58.  
  59. def __xor__(self, other): 
  60.  
  61. if isinstance(other, bool): 
  62.  
  63. return bool(int(self) ^ int(other)) 
  64.  
  65. else
  66.  
  67. return int.__xor__(self, other) 
  68.  
  69.  
  70. __rxor__ = __xor__ 
  71.  
  72.  
  73. # Bootstrap truth values through sheer willpower 
  74.  
  75. False = int.__new__(bool, 0
  76.  
  77. True = int.__new__(bool, 1

False 和 True 將是單例的(singletons),像 None 一樣。因?yàn)檫@種類型有兩個(gè)值,也許應(yīng)該將它們稱為“doubletons”?實(shí)際的實(shí)現(xiàn)將不允許創(chuàng)建 bool 的其它實(shí)例。

True 與 False 會(huì)被正確地序列化和打包,例如 pickle.loads(pickle.dumps(True)) 將返回 True, 而marshal.loads(marshal.dumps(True)) 也一樣。

所有在定義上需返回布爾結(jié)果的內(nèi)置操作,都將更改為返回 False 或 True,而不再是 0 或 1。

具體而言,這會(huì)影響比較操作(<、<=、==、!=、>、>=、is、is not、in、not in),一元運(yùn)算符'not',內(nèi)置函數(shù) callable()、hasattr()、isinstance() 和issubclass() ,字典方法 has_key() ,字符串和 unicode 方法 endswith()、isalnum()、isalpha()、isdigit()、islower()、isspace()、istitle()、isupper() 和startswith(),unicode方法 isdecimal() 和 isnumeric(),以及文件對(duì)象的“closed”屬性。operator 模塊中的斷言方法也被改為返回布爾值,包括operator.truth()。

由于 bool 繼承自 int,因此 True + 1有效且等于 2,依此類推。這對(duì)于向后兼容性很重要:因?yàn)楸容^之類的操作當(dāng)前返回整數(shù)值,所以無法確定現(xiàn)有應(yīng)用程序怎么使用這些值。

預(yù)計(jì)隨著時(shí)間的推移,標(biāo)準(zhǔn)庫將在適當(dāng)?shù)臅r(shí)候更新為使用 False 和 True (但在以前允許使用 int 的場合,則不需要使用 bool 參數(shù)類型)。此更改不應(yīng)引起在本 PEP 中未詳細(xì)說明的其它問題。

C API

“boolobject.h”頭文件為布爾類型定義了 C API。它包含在“Python.h”中,因此不需要再 include 它。

現(xiàn)有的名稱 Py_False 和 Py_True 引用獨(dú)一無二的布爾對(duì)象 False 和 True (之前,它們分別引用了值為 0 和 1 的靜態(tài)整數(shù)對(duì)象,是眾多整數(shù)之一)。

一個(gè)新的 API,即 PyObject *PyBool_FromLong(long) ,會(huì)接收一個(gè) C 長整型參數(shù),并返回對(duì) Py_False (當(dāng)參數(shù)為零時(shí))或 Py_True (當(dāng)非零時(shí))的新引用。

要檢查對(duì)象是否為布爾對(duì)象,可以使用宏 PyBool_Check()。

布爾實(shí)例的類型是 PyBoolObject *。

布爾類型對(duì)象可作為 PyBool_Type 使用。

澄清

本 PEP 沒有改變一個(gè)事實(shí),即幾乎所有類型的對(duì)象都可以用作真假值。例如,在 if 語句中使用時(shí),一個(gè)空列表為 false,一個(gè)非空列表為 true;這不會(huì)改變,而且也不打算改變。

唯一改變的是在返回或賦值時(shí),用于表示真假值的首選值。以前,這些首選的真假值是 1 和 0;本 PEP 將首選值更改為 True 和 False,并修改內(nèi)置操作以返回這些首選值。

兼容性

因?yàn)橐蚝蠹嫒?,所以布爾類型擁有一些不?yán)格的屬性。例如,允許使用布爾參數(shù)進(jìn)行算術(shù)運(yùn)算,即將 False 視為 0,將 True 視為 1。而且,可以將 bool 用作序列對(duì)象的索引。

我不認(rèn)為這是一個(gè)問題,也不希望朝這個(gè)方向發(fā)展語言。我認(rèn)為,對(duì)“布爾性(Booleanness)”的更嚴(yán)格的解釋不會(huì)使語言更清晰。

兼容性要求的另一個(gè)結(jié)果是表達(dá)式“True and 6”的值為 6,類似地,表達(dá)式“ False or None”的值為 None。

“and”和“or”運(yùn)算符被設(shè)計(jì)來返回第一個(gè)決定了結(jié)果的參數(shù),這點(diǎn)不會(huì)改變;特別地,它們不強(qiáng)制要求結(jié)果為布爾類型。當(dāng)然,如果兩個(gè)參數(shù)都是布爾值,那么結(jié)果肯定是一個(gè)布爾值。通過寫“bool(x and y)”,也可以很容易地將其強(qiáng)制轉(zhuǎn)成布爾類型。

解決了的問題

(另請(qǐng)參見上面的“評(píng)審”部分。)

  • 由于 bool 值的 repr() 或 str() 與 int 值不同,因此某些代碼(例如,基于doctest 的單元測試,以及可能依賴于 “%s”%truth 的數(shù)據(jù)庫代碼)可能會(huì)出錯(cuò)。解決這個(gè)問題很容易(無需顯式引用 bool 類型),并且預(yù)計(jì)這只會(huì)影響非常少量的可以輕松修復(fù)的代碼。

  • 其它語言(C99、C ++、Java)均以小寫形式命名常量“false”和“true”。對(duì)于Python,我更喜歡遵照現(xiàn)有內(nèi)置常量的慣例,這些內(nèi)置常量全部使用駝峰式命名:None 、Ellipsis、NotImplemented (以及所有的內(nèi)置異常)。Python 內(nèi)置的命名空間全部用小寫字母表示函數(shù)和類型。

  • 前面提到過,為了滿足用戶的期望,對(duì)于在布爾上下文中被認(rèn)為是真的每個(gè) x, x == True 表達(dá)式都應(yīng)該為真,同樣,如果 x 被認(rèn)為是假,則 x == False 也應(yīng)該為真。那些剛了解布爾變量的新手可能會(huì)寫:

 

  1. if x == True: ... 
而不是正確的形式:

 

 

  1. if x: ... 
許多人乍一看會(huì)對(duì)后一種形式感到不舒服,這在心理和語言上似乎有很強(qiáng)的理由,但是我認(rèn)為解決辦法應(yīng)該是教育而不是削弱語言。

 

畢竟,== 通常被視為傳遞符號(hào),這意味著根據(jù) a == b 和 b == c,可以推論出 a == c。但是,如果在一個(gè)數(shù)是真值的情況下,它與 True 進(jìn)行比較的結(jié)果是相等的,則像 6 == True == 7 這樣的暴行將成立,從而可以推斷出錯(cuò)誤的 6 == 7。那是不可接受的。(此外,它會(huì)破壞向后兼容性。但是,即使它不破壞,出于前面的原因,我仍然反對(duì)。)

還應(yīng)該提醒新手,沒有理由寫:

 

  1. if bool(x): ... 
因?yàn)椴紶栔惦[含在“if”中。在這里,顯式并  比隱式好,因?yàn)樘砑拥脑~法會(huì)損害可重用性,并且限制了解釋器的解釋行為。 (譯注:”The Zen of Python“中認(rèn)為”顯式比隱式好“,但在這里,Guido 認(rèn)為隱式更好,所以他在原文檔中加粗了”not“)

 

但是,有時(shí)候有理由寫成:

 

  1. b = bool(x) 
當(dāng)不需要保留對(duì)任意 x 對(duì)象的引用時(shí),或者由于某些其它原因需要規(guī)范化時(shí),這很有用。有時(shí)候這樣寫也很合適:

 

 

  1. i = int(bool(x)) 
它將布爾值轉(zhuǎn)換為整數(shù)的 0 或 1。傳達(dá)了將該值用作 int 的意圖。

 

實(shí)現(xiàn)

完整的 C 實(shí)現(xiàn)代碼已上傳到 SourceForge 補(bǔ)丁管理器:https://bugs.python.org/issue528022

它將很快被合入到 python 2.3a0 的 CVS 中。

版權(quán)

本文檔已進(jìn)入公共領(lǐng)域。

源文檔: https://github.com/python/peps/blob/master/pep-0285.txt

更多的 PEP 中文翻譯內(nèi)容,可在 Github 查閱:https://github.com/chinesehuazhou/peps-cn

 

責(zé)任編輯:張燕妮 來源: Python貓
相關(guān)推薦

2020-12-30 07:55:37

C++轉(zhuǎn)換類型

2021-03-11 14:46:05

C++類型轉(zhuǎn)換語言

2021-12-03 17:22:09

CC++編程語言

2013-02-28 09:42:25

DIND 10C++Python

2022-11-28 09:58:58

C++開發(fā)

2010-09-16 17:53:12

Java編譯

2010-01-22 15:14:37

學(xué)習(xí)C++

2010-01-20 14:03:12

C++程序

2024-01-24 11:24:03

C++編程異常處理

2010-01-28 13:45:06

C++數(shù)組

2020-09-25 15:41:16

C++JavaPython

2021-11-19 09:49:00

CC++語法糖

2010-01-28 16:31:54

C++類型

2018-06-07 15:15:36

PHPPythonJava

2014-04-24 13:43:37

CC++單元測試框架

2009-08-12 18:16:47

C#類型比較

2021-10-19 14:04:28

C++類型數(shù)字

2025-04-30 10:10:00

在 C++C++11Lambda

2016-12-20 16:35:52

NodeJSC++類型轉(zhuǎn)換

2016-12-07 11:23:52

NodeJSC++
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 美女黄频 | 国产视频二区 | 亚洲欧美激情精品一区二区 | 在线播放国产一区二区三区 | 免费看一级毛片 | 国产伦精品 | 亚洲国产成人精品女人 | 99精品一区二区三区 | 亚洲国产精品成人久久久 | 国产精品久久国产精品 | 国产日韩在线观看一区 | 国产亚洲欧美在线 | 日本三级全黄三级三级三级口周 | 亚洲天堂日韩精品 | 日韩一二三区视频 | xx视频在线 | 日韩精品视频网 | 一区欧美 | 羞羞色视频 | 成人午夜视频在线观看 | 91欧美激情一区二区三区成人 | 日本午夜免费福利视频 | www国产成人免费观看视频 | 国产精品视频一区二区三区 | 亚洲一区二区免费 | 毛片久久久| 日日碰狠狠躁久久躁96avv | 亚洲一区中文字幕在线观看 | 婷婷国产一区二区三区 | 夜夜爽夜夜操 | 精品国产精品一区二区夜夜嗨 | 午夜av免费 | av中文在线 | 久久精品av麻豆的观看方式 | 精品少妇一区二区三区日产乱码 | 亚洲激情网站 | 日韩成人在线看 | 欧美激情亚洲 | 99久久精品国产一区二区三区 | 九九亚洲| av永久|