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

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

簡(jiǎn)單語句

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

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á)式語句

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

expression_stmt ::=  expression_list

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

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

賦值語句

使用賦值把名字綁定(重新綁定)到值,以及修改可變對(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的基本語法定義部分。)

一個(gè)賦值語句要對(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è)異常。被各種類型所遵循的規(guī)則和拋出的異常給出針對(duì)對(duì)象類型的定義(見標(biāo)準(zhǔn)的類型層次結(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語句當(dāng)中:該名字就約束到當(dāng)前本地命名空間的對(duì)象上。
    • 否則:該名字分別約束到全局名字空間或者nolocal確定的外部名字空間。

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

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

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

注意:如果對(duì)象是類的實(shí)例并且屬性引用的賦值操作發(fā)生在兩端,RHS 表達(dá)式,a.x既能訪問一個(gè)實(shí)例屬性,也能(如果沒有實(shí)例屬性存在)訪問一個(gè)類的屬性。這個(gè)LHS目標(biāo)a.x通常設(shè)定一個(gè)實(shí)例屬性,如果有必要就創(chuàng)建。因此,這兩個(gè)a.x的發(fā)生不需要涉及同樣的屬性,如果RHS表達(dá)式涉及到類的屬性,這個(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ù),序列的長度就被加上。最后的值必須是一個(gè)小于該序列長度的非負(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)的類型必須和映射的鍵類型兼容,接著該映射就被 要求創(chuàng)建一個(gè)把下標(biāo)映射到被賦對(duì)象的鍵/數(shù)據(jù)對(duì)。這(操作)要不用新鍵值取代已存在的具有相同 鍵的鍵/值對(duì),要不插入一個(gè)新的鍵/值對(duì)(如果不存在相同的鍵)

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

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

CPython實(shí)現(xiàn)細(xì)節(jié):在當(dāng)前實(shí)現(xiàn)中,目標(biāo)對(duì)象的語法采取同一表達(dá)式,同時(shí)無效的語法在代碼生成階段內(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)

參見:
PEP 3132 - Extended Iterable Unpacking
The specification for the *target feature.

增量的賦值語句

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

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

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

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

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

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

除了在一條語句中賦值給元組和多個(gè)對(duì)象的情況,增量賦值語句所完成的賦值用與普通賦值同樣的方式處理。類似地,除了可能的就地方式,由增量賦值執(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 語句

assert語句是一個(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__ 在普通情況下為True, 在要求優(yōu)化的情況下為False(命令行選項(xiàng)-O) 在編譯要求優(yōu)化時(shí), 當(dāng)前的代碼生成器不產(chǎn)生任何斷言語句的代碼.注意在錯(cuò)誤信息包括源代碼的作法是多余的; 因?yàn)樗鼈儠?huì)作為跟蹤回溯對(duì)象的一部分顯示。

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

pass 語句

    pass_stmt ::=  "pass"

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

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

del 語句

del_stmt ::=  "del" target_list

與賦值的定義方法類似,刪除也是遞歸的。下面是一些說明:

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

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

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

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

return 語句

return_stmt ::=  "return" [expression_list]

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

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

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

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

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

yield 語句

yield_stmt ::=  yield_expression

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

    yield <expr>
    yield from <expr>

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

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

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

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

raise 語句

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

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

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

異常的類型是異常實(shí)例類,是實(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è)異常類或?qū)嵗?,然后將附加到?__cause__ 屬性 (它是可寫)引發(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è)類似的機(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é),處理異常的信息Try語句章節(jié)。

break 語句

    break_stmt ::=  "break"

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

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

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

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

continue 語句

    continue_stmt ::=  "continue"

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

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

import 語句

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語句(不是from子句)執(zhí)行下面兩個(gè)步驟:

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

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

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

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

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

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

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

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

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

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)('*')取代,該模塊中定義的所有公共名稱,都在import語句所在的本地命名空間中被約束。

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

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

在指定你要導(dǎo)入的模塊時(shí),你并不一定要指定模塊的絕對(duì)名字。當(dāng)一個(gè)模塊或包是在其他包之內(nèi)時(shí),在同一個(gè)頂層包下,我們有可能使用不需指明包名的相對(duì)加載。通過在from之后的模塊或者包之前指定幾個(gè)句號(hào), 就可以在沒有精確名字的情況下,指定在當(dāng)前包層次中向上搜索多少層。一個(gè)句號(hào)代表包括導(dǎo)入操作所在模塊的當(dāng)前包。兩個(gè)句號(hào)代表上一個(gè)包層次,三個(gè)句號(hào)代表再上一個(gè)包層次,依次類推。所以,如果你在 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ī)范參見PEP328

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

future 語句

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

future語句旨在緩解未來版本Python的遷移,這類版本會(huì)引入語言不兼容的變化。在發(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語句必須出現(xiàn)在模塊的頂部。唯一能出現(xiàn)在future前面的語句是:

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

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

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

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

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

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

請(qǐng)注意,沒有什么特別的語句。

    import __future__ [as name]

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

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

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

參見:
PEP 236 - Back to the future
The original proposal for the future mechanism.

global 語法

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

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

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

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

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

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

nonlocal 語句

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

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

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

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

參見:
PEP 3104 - Access to Names in Outer Scopes
The specification for the nonlocal statement.

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