在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Python/ 簡(jiǎn)單語(yǔ)句
復(fù)合語(yǔ)句
數(shù)據(jù)模型
完整的語(yǔ)法規(guī)范
執(zhí)行模型
表達(dá)式
導(dǎo)入系統(tǒng)
詞法分析
簡(jiǎn)單語(yǔ)句
頂層組件
介紹

簡(jiǎn)單語(yǔ)句

簡(jiǎn)單語(yǔ)句可以在一個(gè)邏輯行內(nèi)表示,一些簡(jiǎn)單語(yǔ)句可以寫(xiě)在一行由分號(hào)分隔,簡(jiǎn)單語(yǔ)句的句法如下:

simple_stmt ::=  expression_stmt
                 | assert_stmt
                 | assignment_stmt
                 | augmented_assignment_stmt
                 | pass_stmt
                 | del_stmt
                 | return_stmt
                 | yield_stmt
                 | raise_stmt
                 | break_stmt
                 | continue_stmt
                 | import_stmt
                 | global_stmt
                 | nonlocal_stmt

表達(dá)式語(yǔ)句

表達(dá)式語(yǔ)句用于計(jì)算和寫(xiě)一個(gè)值(多用在交互方式下), 或者(通常)調(diào)用過(guò)程(一個(gè)返回沒(méi)有意義的結(jié)果的函數(shù); 在Python中,過(guò)程返回None)。允許其它表達(dá)式語(yǔ)句的使用方法,有時(shí)也用的到。表達(dá)式語(yǔ)句的句法如下:

expression_stmt ::=  expression_list

一個(gè)表達(dá)式語(yǔ)句要對(duì)該表達(dá)式列表(可能只是一個(gè)表達(dá)式)求值.

在交互模式下,如果該值不是空,就使用內(nèi)建函數(shù)repr()并自己將結(jié)果字符串寫(xiě)入一行標(biāo)準(zhǔn)輸出,(除非結(jié)果為空,導(dǎo)致過(guò)程調(diào)用不會(huì)引起任何輸出。)

賦值語(yǔ)句

使用賦值把名字綁定(重新綁定)到值,以及修改可變對(duì)象的屬性或者項(xiàng)目:

assignment_stmt ::=  (target_list "=")+ (expression_list | yield_expression)
target_list     ::=  target ("," target)* [","]
target          ::=  identifier
                     | "(" target_list ")"
                     | "[" target_list "]"
                     | attributeref
                     | subscription
                     | slicing
                     | "*" target

(請(qǐng)參閱 attributeref、 subscription和slicing的基本語(yǔ)法定義部分。)

一個(gè)賦值語(yǔ)句要對(duì)該表達(dá)式列表求值(請(qǐng)記住這可以是一個(gè)表達(dá)式或者一個(gè)逗號(hào)分隔的列表,后者導(dǎo)出一個(gè)元組),然后從左到右地將對(duì)象結(jié)果依次賦給目的列表里的每個(gè)對(duì)象。

根據(jù)目標(biāo)(列表)的形式,賦值被遞歸地定義。當(dāng)目標(biāo)是一個(gè)可變對(duì)象的一部分時(shí)(一個(gè)屬性引用,subscription或者slicing),可變的對(duì)象必須最終執(zhí)行賦值,并確定其有效性,如果在賦值不可接受的情況下,可以引發(fā)出一個(gè)異常。被各種類(lèi)型所遵循的規(guī)則和拋出的異常給出針對(duì)對(duì)象類(lèi)型的定義(見(jiàn)標(biāo)準(zhǔn)的類(lèi)型層次結(jié)構(gòu)部分)。

分配對(duì)象到目標(biāo)列表,括號(hào)或方括號(hào)內(nèi)為可選,遞歸地定義如下.

  • 如果目標(biāo)列表是單個(gè)目標(biāo),該對(duì)象就賦予該目標(biāo)。
  • 如果目標(biāo)序列是一組用逗號(hào)分隔的目標(biāo):該對(duì)象必須是一個(gè)其子項(xiàng)個(gè)數(shù)與目標(biāo)列表中的目標(biāo)個(gè)數(shù) 一樣多的迭代對(duì)象,且其子項(xiàng),從左到右地逐個(gè)賦予相應(yīng)目標(biāo)。
    • 如果目標(biāo)列表包含一個(gè)前綴帶星號(hào)的目標(biāo),被成為“starred”目標(biāo):這個(gè)對(duì)象必須是一個(gè)序列在目標(biāo)列表中,有盡量多的子項(xiàng)目,不能少于一個(gè)子項(xiàng)目,序列從第一項(xiàng)被賦值,在帶星的目標(biāo)之前,從左到右逐個(gè)分配到目標(biāo)列表。序列最后一項(xiàng)被賦值,則賦值到星號(hào)之后的目標(biāo)。列表中剩余的項(xiàng)目最后被賦值給帶星的目標(biāo)(列表可以是空的)。
    • 否則:這個(gè)對(duì)象必須是一個(gè)在目標(biāo)列表中有相同數(shù)目子項(xiàng)的序列,并且子項(xiàng)從左到右地賦予相應(yīng)目標(biāo)。

一個(gè)對(duì)象向單個(gè)目標(biāo)遞歸地賦值定義如下。

  • 如果該目標(biāo)是一個(gè)標(biāo)志符(名字):

    • 如果該名字不出現(xiàn)于當(dāng)前代碼塊的global或者nolocal語(yǔ)句當(dāng)中:該名字就約束到當(dāng)前本地命名空間的對(duì)象上。
    • 否則:該名字分別約束到全局名字空間或者nolocal確定的外部名字空間。

如果名字已經(jīng)被約束了它就被重新約束。這可能導(dǎo)致早先約束到該名字的對(duì)象的引用計(jì)數(shù)降為 零,導(dǎo)致釋放該對(duì)象的分配空間并調(diào)用其析構(gòu)器,如果它有一個(gè)的話(huà)。

  • 如果目標(biāo)是一個(gè)用括號(hào)或者方括號(hào)括起來(lái)的目標(biāo)序列:該對(duì)象必須是具有和目標(biāo)序列中目標(biāo)個(gè)數(shù)同樣數(shù)目的迭代類(lèi)型,且其子項(xiàng)從左到右地賦值給相應(yīng)目標(biāo)。

  • 如果目標(biāo)是一個(gè)屬性引用:引用中的主元表達(dá)式被求值。它應(yīng)該給出一個(gè)帶可賦值屬性的對(duì)象; 如果不是這種情況,就會(huì)拋出TypeError異常。然后那個(gè)對(duì)象就被要求將被賦值的對(duì)象賦值給給定 的屬性;如果它無(wú)法執(zhí)行該賦值,就會(huì)拋出一個(gè)例外(通常,但不是必須AttributeError異常)。

注意:如果對(duì)象是類(lèi)的實(shí)例并且屬性引用的賦值操作發(fā)生在兩端,RHS 表達(dá)式,a.x既能訪(fǎng)問(wèn)一個(gè)實(shí)例屬性,也能(如果沒(méi)有實(shí)例屬性存在)訪(fǎng)問(wèn)一個(gè)類(lèi)的屬性。這個(gè)LHS目標(biāo)a.x通常設(shè)定一個(gè)實(shí)例屬性,如果有必要就創(chuàng)建。因此,這兩個(gè)a.x的發(fā)生不需要涉及同樣的屬性,如果RHS表達(dá)式涉及到類(lèi)的屬性,這個(gè)LHS會(huì)創(chuàng)建一個(gè)新的實(shí)例屬性作為賦值的目標(biāo)。

    class Cls:
    x = 3                 # class variable
    inst = Cls()
    inst.x = inst.x + 1   # writes inst.x as 4 leaving Cls.x as 3

這個(gè)描述并不一定適用于描述符屬性,像屬性創(chuàng)建使用property()。

  • 如果目標(biāo)是一個(gè)下標(biāo):引用中的主元表達(dá)式被求值。這應(yīng)給出或者一個(gè)可變有序?qū)ο?比如,一個(gè)列表)或者一個(gè)映射對(duì)象(比如,一個(gè)字典)。接著,下標(biāo)表達(dá)式被求值。

如果基礎(chǔ)對(duì)象是可變有序?qū)ο?例如列表),下標(biāo)必須給出一個(gè)整數(shù)。如果是負(fù)數(shù),序列的長(zhǎng)度就被加上。最后的值必須是一個(gè)小于該序列長(zhǎng)度的非負(fù)整數(shù),然后該序列就被請(qǐng)求將被賦對(duì)象賦值給 它帶那個(gè)指標(biāo)的項(xiàng)。如果指標(biāo)超出范圍,就會(huì)拋出IndexError異常(給一個(gè)用下標(biāo)引用的有序?qū)ο筚x 值不會(huì)給列表增添新項(xiàng))

如果基礎(chǔ)對(duì)象是一個(gè)映射對(duì)象(比如字典),下標(biāo)的類(lèi)型必須和映射的鍵類(lèi)型兼容,接著該映射就被 要求創(chuàng)建一個(gè)把下標(biāo)映射到被賦對(duì)象的鍵/數(shù)據(jù)對(duì)。這(操作)要不用新鍵值取代已存在的具有相同 鍵的鍵/值對(duì),要不插入一個(gè)新的鍵/值對(duì)(如果不存在相同的鍵)

用戶(hù)自定義的對(duì)象, ____setitem__ __()方法被調(diào)用以適當(dāng)?shù)膮?shù)。

  • 如果目標(biāo)是一片斷:引用中的主元表達(dá)式被求值。這應(yīng)給出一個(gè)可變有序?qū)ο?比如列表)。被賦值 對(duì)象應(yīng)該是同一類(lèi)型的有序?qū)ο?。下一步,在它們所出現(xiàn)的范圍內(nèi),對(duì)上下限表達(dá)式求值;缺省值是零和序列長(zhǎng)度。限值應(yīng)求值為整數(shù)。如果任一限是負(fù)的,就加上序列的長(zhǎng)度。結(jié)果限值被修整至零和序列長(zhǎng)度之間(含零和序列長(zhǎng)度)。最后,有序?qū)ο蟊灰笥帽毁x有序?qū)ο蟮淖禹?xiàng)替換該片斷。片斷的長(zhǎng)度可能和被賦序列的長(zhǎng)度不同,那就改變目標(biāo)序列的長(zhǎng)度,如果該對(duì)象允許的話(huà)。

CPython實(shí)現(xiàn)細(xì)節(jié):在當(dāng)前實(shí)現(xiàn)中,目標(biāo)對(duì)象的語(yǔ)法采取同一表達(dá)式,同時(shí)無(wú)效的語(yǔ)法在代碼生成階段內(nèi)被拒絕,導(dǎo)致更少的詳細(xì)的錯(cuò)誤消息輸出.

雖然賦值的定義隱含著左手邊和右手邊之間的重疊是“同時(shí)的”(比如,a, b = b, a交換兩個(gè)變量),在所賦值變量間的重疊卻是不安全的!在集合中出現(xiàn)從左到右分配變量間的重疊是不安全的,有時(shí)候值是混亂的,例如,下面的程序打印出[0, 2]

    x = [0, 1]
    i = 0
    i, x[i] = 1, 2 # i is updated, then x[i] is updated
    print(x)

參見(jiàn):
PEP 3132 - Extended Iterable Unpacking
The specification for the *target feature.

增量的賦值語(yǔ)句

增量賦值就是在單條語(yǔ)句內(nèi)合并一個(gè)二元運(yùn)算和一個(gè)賦值語(yǔ)句。

augmented_assignment_stmt ::=  augtarget augop (expression_list | yield_expression)
augtarget                 ::=  identifier | attributeref | subscription | slicing
augop                     ::=  "+=" | "-=" | "*=" | "/=" | "http://=" | "%=" | "**="
                               | ">>=" | "<<=" | "&=" | "^=" | "|="

(見(jiàn)最后三項(xiàng)符號(hào)基礎(chǔ)語(yǔ)法定義)

一條增量賦值語(yǔ)句對(duì)目標(biāo)(和一般的賦值語(yǔ)句不同,它不能是展開(kāi)的對(duì)象)和表達(dá)式列表求值,執(zhí)行特定于兩個(gè)操作數(shù)的賦值類(lèi)型的二元運(yùn)算,并將結(jié)果賦值給原先的目標(biāo)。目標(biāo)僅求值一次。

一條賦值語(yǔ)句,比如x+=1, 可以重寫(xiě)為x=x+1,效果是類(lèi)似的,但并不完全一樣。在增量版本中,x僅求值一次。而且,只要可能,實(shí)際的操作是就地進(jìn)行的,意思是并非創(chuàng)建一個(gè)新對(duì)象然后將其賦值給目標(biāo),而是修改老的對(duì)象。

不像普通的賦值語(yǔ)句,增量賦值先計(jì)算左邊再計(jì)算右邊。例如,a[i] += f (x) 首先查看a[i],然后它計(jì)算 f(x) 并執(zhí)行加法操作,最后,把結(jié)果寫(xiě)入a[i]。

除了在一條語(yǔ)句中賦值給元組和多個(gè)對(duì)象的情況,增量賦值語(yǔ)句所完成的賦值用與普通賦值同樣的方式處理。類(lèi)似地,除了可能的就地方式,由增量賦值執(zhí)行的二元運(yùn)算和普通的二元運(yùn)算也是一樣的。

For targets which are attribute references, the same caveat about class and instance attributes applies as for regular assignments.

assert 語(yǔ)句

assert語(yǔ)句是一個(gè)在程序中插入調(diào)試斷言的常用方法:

assert_stmt ::= "assert" expression ["," expression]

簡(jiǎn)單形式的, ”assert expression”, 等價(jià)于:

    if __debug__:
       if not expression: raise AssertionError

擴(kuò)展形式的, ”assert expression”, 等價(jià)于:

    if __debug__:
       if not expression1: raise AssertionError(expression2)

這些等價(jià)式假定了存在__debug__AssertionError, 而不是具有相同名字的相應(yīng)內(nèi)建變量.在當(dāng)前實(shí)現(xiàn), 內(nèi)建變量 __debug__ 在普通情況下為T(mén)rue, 在要求優(yōu)化的情況下為False(命令行選項(xiàng)-O) 在編譯要求優(yōu)化時(shí), 當(dāng)前的代碼生成器不產(chǎn)生任何斷言語(yǔ)句的代碼.注意在錯(cuò)誤信息包括源代碼的作法是多余的; 因?yàn)樗鼈儠?huì)作為跟蹤回溯對(duì)象的一部分顯示。

__debug__賦值是非法的,解釋器是在啟動(dòng)時(shí)讀取內(nèi)建變量的值的。

pass 語(yǔ)句

    pass_stmt ::=  "pass"

pass是一個(gè)空操作 - 當(dāng)執(zhí)行它,什么也不會(huì)做。它在句法上要求有一個(gè)語(yǔ)句時(shí)但不需要寫(xiě)代碼時(shí)用到,例如:

    def f(arg): pass   # a function that does nothing (yet)
    class C: pass      # a class with no methods (yet)

del 語(yǔ)句

del_stmt ::=  "del" target_list

與賦值的定義方法類(lèi)似,刪除也是遞歸的。下面是一些說(shuō)明:

一個(gè)目標(biāo)表的遞歸刪除操作會(huì)從左到右地刪除其中的每個(gè)對(duì)象地.

刪除名字就是在本地命名空間和全局名字空間刪除掉該名字的綁定(必須存在), 從哪個(gè)名字空間刪除取決于該名字是否出現(xiàn)在其代碼塊的global語(yǔ)句中。如果名字沒(méi)有綁定,會(huì)拋出NameError異常。

對(duì)于屬性引用, 下標(biāo)和片斷的刪除會(huì)作用到相關(guān)的主元對(duì)象, 對(duì)片斷的刪除一般等價(jià)于對(duì)該片斷賦予相應(yīng) 類(lèi)型的空片斷(但這也受被截為片斷的對(duì)象的限制).

3.2版本變化:之前如果嵌套數(shù)據(jù)塊中有空變量,在本地命名空間中刪除名字是不合法的。

return 語(yǔ)句

return_stmt ::=  "return" [expression_list]

return在句法上僅可以出現(xiàn)在嵌套的函數(shù)定義中, 不能出現(xiàn)在嵌套的類(lèi)定義中.

如果給出了表達(dá)式表, 就計(jì)算其值, 否則就用None代替.

return的作用是離開(kāi)當(dāng)前函數(shù)調(diào)用, 并以表達(dá)式表的值(或None)為返回值.

當(dāng)return放在具有?nally子句的try語(yǔ)句中, ?nally子句中的語(yǔ)句會(huì)在函數(shù)真正退出之前執(zhí)行一次.

在生成器函數(shù)中, return語(yǔ)句意味著生成器執(zhí)行完成,并且將會(huì)引發(fā)一個(gè)StopIteration異常。返回值(如果有的話(huà))是作為StopIteration構(gòu)造方法的參數(shù),并且會(huì)變成StopIteration.value屬性。

yield 語(yǔ)句

yield_stmt ::=  yield_expression

yield語(yǔ)句在語(yǔ)義上等同于yield表達(dá)式。yield語(yǔ)法被用來(lái)省略括號(hào),否則需要使用相同的yield表達(dá)式語(yǔ)句。例如,yield語(yǔ)句

    yield <expr>
    yield from <expr>

等同于yield表達(dá)式語(yǔ)句

    (yield <expr>)
    (yield from <expr>)

yield表達(dá)式和語(yǔ)句只有當(dāng)在定義生成器函數(shù)時(shí)被使用。只使用在生成器函數(shù)體中。在函數(shù)定義時(shí)使用yield,足夠?qū)е露x一個(gè)創(chuàng)建生成器函數(shù)而不是普通函數(shù)。

yield詳細(xì)的語(yǔ)法,參考yield表達(dá)式部分。

raise 語(yǔ)句

raise_stmt ::=  "raise" [expression ["from" expression]]

如果不給出表達(dá)式,raise重新引發(fā)當(dāng)前范圍內(nèi)上次引發(fā)的異常。如果當(dāng)前范圍沒(méi)有可用的異常,會(huì)拋出RuntimeError異常,暗示出現(xiàn)錯(cuò)誤。

否則,raise使用第一個(gè)表達(dá)式作為異常對(duì)象求值。 對(duì)異常對(duì)象的第一個(gè)表達(dá)式求值。他必須是一個(gè)子類(lèi)或者一個(gè)BaseException的實(shí)例。如果是一個(gè)類(lèi),當(dāng)實(shí)例化一個(gè)無(wú)參數(shù)類(lèi)被需要的時(shí)候,異常實(shí)例將被獲取,

異常的類(lèi)型是異常實(shí)例類(lèi),是實(shí)例本身。

traceback對(duì)象通常被自動(dòng)創(chuàng)建,當(dāng)異常發(fā)生并且被附加到它的 traceback 屬性上。你可以創(chuàng)建異常并設(shè)置你自己的traceback,在第一步使用異常方法with _traceback()(這個(gè)方法返回相同的異常實(shí)例,traceback設(shè)置到他的參數(shù)中),就像:

    raise Exception("foo occurred").with_traceback(tracebackobj)

from子句用于異常鏈接:如果給出,則第二個(gè)表達(dá)式必須是另一個(gè)異常類(lèi)或?qū)嵗?,然后將附加到?__cause__ 屬性 (它是可寫(xiě))引發(fā)的異常。如果不處理引發(fā)的異常,則將打印兩個(gè)例外情況:

    >>>>>>>>> try:
    ... print(1 / 0)
    ... except Exception as exc:
    ... raise RuntimeError("Something bad happened") from exc
    ...
    Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
    ZeroDivisionError: int division or modulo by zero

    The above exception was the direct cause of the following exception:

    Traceback (most recent call last):
      File "<stdin>", line 4, in <module>
    RuntimeError: Something bad happened

一個(gè)類(lèi)似的機(jī)制隱式工作如果里面的異常處理程序引發(fā)的異?;?finally 子句: 那么前一個(gè)異常附加作為新異常 __context__ 屬性:

    >>>>>>>>> try:
    ... print(1 / 0)
    ... except:
    ... raise RuntimeError("Something bad happened")
    ...
    Traceback (most recent call last):
      File "<stdin>", line 2, in <module>
    ZeroDivisionError: int division or modulo by zero

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "<stdin>", line 4, in <module>
    RuntimeError: Something bad happened

更多異常信息見(jiàn)異常章節(jié),處理異常的信息Try語(yǔ)句章節(jié)。

break 語(yǔ)句

    break_stmt ::=  "break"

break在句法上只能出現(xiàn)在forwhile循環(huán)中, 但不能出現(xiàn)在循環(huán)中的函數(shù)定義或類(lèi)定義中。

它中斷最內(nèi)層的循環(huán), 跳過(guò)其可選的else語(yǔ)句(如果有的話(huà))。

如果for循環(huán)被break中斷, 它的循環(huán)控制對(duì)象還保持當(dāng)前值。

當(dāng)break放在具有?nally子句的try語(yǔ)句中, ?nally子句中的語(yǔ)句會(huì)在循環(huán)真正退出之前執(zhí)行一次。

continue 語(yǔ)句

    continue_stmt ::=  "continue"

continue在句法上只能出現(xiàn)在forwhile循環(huán)中, 但不能出現(xiàn)在循環(huán)中的函數(shù)定義或類(lèi)定義,或在循環(huán)內(nèi)部的finally子句。 它重新開(kāi) 始最內(nèi)層的循環(huán)。

當(dāng)continue通行控制離開(kāi)一個(gè)包含finally子句的try語(yǔ)句,finally子句執(zhí)行之前真的開(kāi)始下一個(gè)循環(huán)周期。

import 語(yǔ)句

import_stmt     ::=  "import" module ["as" name] ( "," module ["as" name] )*
                     | "from" relative_module "import" identifier ["as" name]
                     ( "," identifier ["as" name] )*
                     | "from" relative_module "import" "(" identifier ["as" name]
                     ( "," identifier ["as" name] )* [","] ")"
                     | "from" module "import" "*"
module          ::=  (identifier ".")* identifier
relative_module ::=  "."* module | "."+
name            ::=  identifier

基本的import語(yǔ)句(不是from子句)執(zhí)行下面兩個(gè)步驟:

  1. 查找module,如果需要加載并且初始化它。
  2. 定義一個(gè)或多個(gè)名稱(chēng)在本地命名空間,在import語(yǔ)句出現(xiàn)的范圍內(nèi)。

當(dāng)語(yǔ)句包含多個(gè)子句(由逗號(hào)分隔)分別對(duì)每個(gè)子句實(shí)施兩個(gè)步驟,就像子句被分隔成個(gè)體的import語(yǔ)句。

詳細(xì)的第一步,查找并加載模塊更詳細(xì)的描述在import system部分,它同樣描述可以被導(dǎo)入的模塊和各種類(lèi)型的包,以及所有的鉤子可用于自定義導(dǎo)入系統(tǒng)。請(qǐng)注意在此步驟中的失敗可能表明該模塊無(wú)法找到,或者模塊初始化錯(cuò)誤,包含可執(zhí)行模塊的代碼錯(cuò)誤。

如果請(qǐng)求的模塊檢測(cè)到成功,它將提供局部空間中的三種方式中的一種:

  • 如果模塊名后跟as,那么這個(gè)名字后as會(huì)直接綁定到導(dǎo)入的模塊。

  • 如果沒(méi)有指定其他名字,并且被導(dǎo)入的是頂層模塊,模塊名被綁定在本地的命名空間作為引用導(dǎo)入模塊。

  • 如果導(dǎo)入不是頂層模塊,那么包含該模塊的頂層包名被綁定到本地命名空間,作為一個(gè)頂級(jí)包的引用。導(dǎo)入的模塊,必須可以使用完全限定名稱(chēng)訪(fǎng)問(wèn)而不是直接訪(fǎng)問(wèn)。

from方式的使用過(guò)程稍微復(fù)雜:

  1. 查找from子句中指定的模塊,如果需要加載并初始化它。
  2. 對(duì)于每一個(gè)import子句的指定標(biāo)識(shí)符:
    1. 檢查import的模塊具有該屬性的名稱(chēng)
    2. 如果沒(méi)有,嘗試根據(jù)名稱(chēng)導(dǎo)入子模塊,然后在導(dǎo)入的模塊中再次檢查該屬性。
  3. 如果屬性沒(méi)有找到,拋出ImportError異常。
  4. 否則,在本地命名空間中存儲(chǔ)這個(gè)引用值,如果存在使用as子句里的名稱(chēng),否則使用屬性名

Examples: 例子:

    import foo                # foo imported and bound locally
    import foo.bar.baz        # foo.bar.baz imported, foo bound locally
    import foo.bar.baz as fbb  # foo.bar.baz imported and bound as fbb
    from foo.bar import baz   # foo.bar.baz imported and bound as baz
    from foo import attr      # foo imported and foo.attr bound as attr

如果標(biāo)識(shí)符列表由星號(hào)('*')取代,該模塊中定義的所有公共名稱(chēng),都在import語(yǔ)句所在的本地命名空間中被約束。

一個(gè)模塊所定義的“公共名稱(chēng)”通過(guò)檢查該模塊的命名空間中的名為 __all__ 的變量決定。如果(該變量)有定義,它必須是一個(gè)字符串的有序序列,這些字符串是由該模塊定義或者導(dǎo)入的名字。在 __all__ 中給出的名字都被認(rèn)為是公共的且要求其存在。如果 __all__ 沒(méi)有定義,(該模塊的)公共名字的集合就包含所有在該模塊的名字空間中找到的,不以下劃線(xiàn)(” _ ”)起首的所有名字。

導(dǎo)入的通配符形式 - from module import *- 只允許模塊級(jí)別。試圖在類(lèi)或者函數(shù)中使用它會(huì)拋出SyntaxError

在指定你要導(dǎo)入的模塊時(shí),你并不一定要指定模塊的絕對(duì)名字。當(dāng)一個(gè)模塊或包是在其他包之內(nèi)時(shí),在同一個(gè)頂層包下,我們有可能使用不需指明包名的相對(duì)加載。通過(guò)在from之后的模塊或者包之前指定幾個(gè)句號(hào), 就可以在沒(méi)有精確名字的情況下,指定在當(dāng)前包層次中向上搜索多少層。一個(gè)句號(hào)代表包括導(dǎo)入操作所在模塊的當(dāng)前包。兩個(gè)句號(hào)代表上一個(gè)包層次,三個(gè)句號(hào)代表再上一個(gè)包層次,依次類(lèi)推。所以,如果你在 pkg 包中執(zhí)行 from.import mod ,你就會(huì)導(dǎo)入pkg.mod。如果你從包 pkg.subpkg1 執(zhí)行 from ..subpkg2 import mod ,你就會(huì)導(dǎo)入 pkg.subpkg2.mod。相對(duì)導(dǎo)入的規(guī)范參見(jiàn)PEP328

函數(shù)importlib.import_module()用于支持要確定哪些模塊需要?jiǎng)討B(tài)加載的應(yīng)用程序。

future 語(yǔ)句

future語(yǔ)句是一個(gè)編譯器指令,在指定的將來(lái)的Python版本應(yīng)該可以使用語(yǔ)法或語(yǔ)義去編譯一個(gè)特定的模塊,到那時(shí)Python特性將成為標(biāo)準(zhǔn)。

future語(yǔ)句旨在緩解未來(lái)版本Python的遷移,這類(lèi)版本會(huì)引入語(yǔ)言不兼容的變化。在發(fā)布前它允許在每個(gè)模塊的基礎(chǔ)上使用新特性,發(fā)布后這個(gè)特性將成為標(biāo)準(zhǔn)。

    future_statement ::=  "from" "__future__" "import" feature ["as" name]
      ("," feature ["as" name])*
      | "from" "__future__" "import" "(" feature ["as" name]
      ("," feature ["as" name])* [","] ")"
    feature  ::=  identifier
    name ::=  identifier

future語(yǔ)句必須出現(xiàn)在模塊的頂部。唯一能出現(xiàn)在future前面的語(yǔ)句是:

  • 該模塊的文檔字符串(如果有),
  • 注釋,
  • 空白行,和
  • 其它future語(yǔ)句。

Python 3.0 版本公認(rèn)的特性是absolute_import, division, generators, unicode_literals, print_function, nested_scopeswith_statement。他們都是多余的,因?yàn)樗麄兛偸窃趩⒂脿顟B(tài),同時(shí)只保持向后兼容的可編譯性。

在編程的時(shí)候future語(yǔ)句被識(shí)別出來(lái),并且被特殊地對(duì)待:更改核心構(gòu)建的語(yǔ)義通常是通過(guò)生成不同的代碼來(lái)實(shí)現(xiàn)的。甚至有可能一個(gè)新的功能會(huì)引入一個(gè)新的不兼容的語(yǔ)法(比如一個(gè)新的保留字),在這種情況下,編譯器可能需要用區(qū)別對(duì)待的方式解析模塊。此類(lèi)決定不能被推遲到運(yùn)行時(shí)。

對(duì)于任何發(fā)布的版本,編譯器明確已經(jīng)被定義的功能名稱(chēng),如果future語(yǔ)句包含未知功能時(shí),編譯器會(huì)提示編譯出錯(cuò)。

直接運(yùn)行語(yǔ)義作為任何導(dǎo)入語(yǔ)句都是相同的:這里有一個(gè)標(biāo)準(zhǔn)的__future__模塊,稍后會(huì)解釋?zhuān)?dāng)future語(yǔ)句被執(zhí)行的時(shí)候,將以通用方式被引入。

令人關(guān)注的運(yùn)行時(shí)語(yǔ)義取決于被future語(yǔ)句啟用的特定功能。

請(qǐng)注意,沒(méi)有什么特別的語(yǔ)句。

    import __future__ [as name]

那個(gè)不是future語(yǔ)句;這是一個(gè)普通的導(dǎo)入語(yǔ)句沒(méi)有特殊的語(yǔ)義或語(yǔ)法的限制。

通過(guò)調(diào)用內(nèi)置函數(shù)exec()compile()來(lái)編譯的代碼,此代碼在M模塊發(fā)起,并包含future語(yǔ)句,在默認(rèn)情況下,會(huì)結(jié)合future語(yǔ)句采用新的語(yǔ)法和語(yǔ)義。這可以由可選參數(shù)來(lái)控制去compile()——有關(guān)詳細(xì)信息,請(qǐng)參閱文檔的功能。

在交互式解析器提示符下鍵入future語(yǔ)句,重啟解析器器會(huì)話(huà)生效。如果解析器以-i選項(xiàng)開(kāi)始,且是通過(guò)一個(gè)腳本名去執(zhí)行,同時(shí)這個(gè)腳本包含future語(yǔ)句,它將作用在交互會(huì)話(huà)中,在腳本執(zhí)行后開(kāi)始。

參見(jiàn):
PEP 236 - Back to the future
The original proposal for the future mechanism.

global 語(yǔ)法

global_stmt ::=  "global" identifier ("," identifier)*

global語(yǔ)句是對(duì)整個(gè)代碼塊都有作用的一個(gè)聲明. 它指出其所列的標(biāo)識(shí)符要解釋為全局的.如果某名字在本地命名空間中沒(méi)有定義, 就自動(dòng)使用相應(yīng)的全局名字. 沒(méi)有global是不可能手動(dòng)指定一個(gè)名字是全局的。

global中出現(xiàn)的名字不能在global 之前的代碼中使用.

global中出現(xiàn)的名字不能作為形參, 不能作為for循環(huán)的控制對(duì)象, 不能在類(lèi)定義, 函數(shù)定義, import語(yǔ)句中出現(xiàn).

CPython詳細(xì)實(shí)現(xiàn):當(dāng)前實(shí)現(xiàn)不強(qiáng)制兩個(gè)限制,但程序不應(yīng)該濫用這種自由,作為將來(lái)的實(shí)現(xiàn)可能會(huì)強(qiáng)制他們或默默地改變程序的意義。

程序員注意: global是一個(gè)解析器的指示字. 它僅僅會(huì)對(duì)和global一起解析的代碼有效,尤其是,一個(gè)global語(yǔ)句被包含在字符串或者代碼對(duì)象提供內(nèi)建的exec()函數(shù),并不影響包含該函數(shù)調(diào)用的代碼塊,相同的機(jī)制也應(yīng)用于eval()compile() 函數(shù)。

nonlocal 語(yǔ)句

nonlocal_stmt ::=  "nonlocal" identifier ("," identifier)*

nonlocal語(yǔ)句引發(fā)列出的標(biāo)識(shí)符,適用于不包括global之外最近的封閉范圍,前一個(gè)綁定變量。這是重要的因?yàn)榻壎ǖ哪J(rèn)行為是首先搜索本地命名空間。該語(yǔ)句允許封裝的代碼綁定除了global(模塊)范圍之外,局部作用域的變量。

nonlocal語(yǔ)句不同于那些在global語(yǔ)句中列出的名稱(chēng),必須引用到預(yù)先存在的封閉范圍中的綁定(不能明確的確定要在其中創(chuàng)建一個(gè)新綁定的范圍)。

nonlocal語(yǔ)句中列出的名字,在本地范圍必須不和已經(jīng)存在的綁定沖突。

參見(jiàn):
PEP 3104 - Access to Names in Outer Scopes
The specification for the nonlocal statement.

上一篇:執(zhí)行模型