<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 純 Python 模式 > 原文: [http://docs.cython.org/en/latest/src/tutorial/pure.html](http://docs.cython.org/en/latest/src/tutorial/pure.html) 在某些情況下,需要加速 Python 代碼而不會失去使用 Python 解釋器運行它的能力。雖然可以使用 Cython 編譯純 Python 腳本,但通常只能獲得大約 20%-50%的速度增益。 為了超越這一點,Cython 提供了語言結構,為 Python 模塊添加靜態類型和 cythonic 功能,使其在編譯時運行得更快,同時仍允許對其進行解釋。這是通過增加`.pxd`文件,通過 Python 類型注釋(在 [PEP 484](https://www.python.org/dev/peps/pep-0484/) 和 [PEP 526](https://www.python.org/dev/peps/pep-0526/) 之后)和/或通過導入魔法后可用的特殊函數和裝飾器來實現的`cython`模塊。盡管項目通常會決定使靜態類型信息易于管理的特定方式,但所有這三種方式都可以根據需要進行組合。 雖然通常不建議在`.pyx`文件中編寫直接的 Cython 代碼,但有正當理由這樣做 - 更容易測試和調試,與純 Python 開發人員協作等。在純模式下,您或多或少地受限于可以在 Python 中表達(或至少模擬)的代碼,以及靜態類型聲明。除此之外的任何事情都只能在擴展語言語法的.pyx 文件中完成,因為它取決于 Cython 編譯器的功能。 ## 增加.pxd 使用擴充`.pxd`可以讓原始`.py`文件完全不受影響。另一方面,需要保持`.pxd`和`.py`以使它們保持同步。 雖然`.pyx`文件中的聲明必須與具有相同名稱的`.pxd`文件的聲明完全對應(并且任何矛盾導致編譯時錯誤,請參閱 [pxd 文件](pxd_files.html) ) ,`.py`文件中的無類型定義可以通過`.pxd`中存在的更具體的類型覆蓋并使用靜態類型進行擴充。 如果找到與正在編譯的`.py`文件同名的`.pxd`文件,將搜索 [`cdef`](../userguide/language_basics.html#cdef) 類和 [`cdef`](../userguide/language_basics.html#cdef) / [`cpdef`](../userguide/language_basics.html#cpdef) 的功能和方法。然后,編譯器將`.py`文件中的相應類/函數/方法轉換為聲明的類型。因此,如果有一個文件`A.py`: ```py def myfunction(x, y=2): a = x - y return a + x * y def _helper(a): return a + 1 class A: def __init__(self, b=0): self.a = 3 self.b = b def foo(self, x): print(x + _helper(1.0)) ``` 并添加`A.pxd`: ```py cpdef int myfunction(int x, int y=*) cdef double _helper(double a) cdef class A: cdef public int a, b cpdef foo(self, double x) ``` 然后 Cython 將編譯`A.py`,就像它編寫如下: ```py cpdef int myfunction(int x, int y=2): a = x - y return a + x * y cdef double _helper(double a): return a + 1 cdef class A: cdef public int a, b def __init__(self, b=0): self.a = 3 self.b = b cpdef foo(self, double x): print(x + _helper(1.0)) ``` 注意為了向`.pxd`中的定義提供 Python 包裝器,即可以從 Python 訪問, * Python 可見函數簽名必須聲明為 &lt;cite&gt;cpdef&lt;/cite&gt; (默認參數替換為 &lt;cite&gt;*&lt;/cite&gt; 以避免重復): ```py cpdef int myfunction(int x, int y=*) ``` * 內部函數的 C 函數簽名可以聲明為 &lt;cite&gt;cdef&lt;/cite&gt; : ```py cdef double _helper(double a) ``` * &lt;cite&gt;cdef&lt;/cite&gt; 類(擴展類型)聲明為 &lt;cite&gt;cdef 類&lt;/cite&gt;; * &lt;cite&gt;cdef&lt;/cite&gt; 類屬性必須聲明為 &lt;cite&gt;cdef public&lt;/cite&gt; 如果需要讀/寫 Python 訪問, &lt;cite&gt;cdef readonly&lt;/cite&gt; 用于只讀 Python 訪問,或普通 &lt;cite&gt;cdef&lt;/cite&gt; 用于內部 C 級屬性; * &lt;cite&gt;cdef&lt;/cite&gt; 類方法必須聲明為 &lt;cite&gt;cpdef&lt;/cite&gt; 用于 Python 可見方法或 &lt;cite&gt;cdef&lt;/cite&gt; 用于內部 C 方法。 在上面的例子中, &lt;cite&gt;myfunction()&lt;/cite&gt;中局部變量&lt;cite&gt;和&lt;/cite&gt;的類型不固定,因此是一個 Python 對象。要靜態輸入,可以使用 Cython 的`@cython.locals`裝飾器(參見 [魔法屬性](#magic-attributes) 和 [魔法屬性.pxd](#magic-attributes-pxd)) 。 普通 Python( [`def`](https://docs.python.org/3/reference/compound_stmts.html#def "(in Python v3.7)") )函數不能在`.pxd`文件中聲明。因此,目前不可能在`.pxd`文件中覆蓋普通 Python 函數的類型,例如覆蓋其局部變量的類型。在大多數情況下,將它們聲明為 &lt;cite&gt;cpdef&lt;/cite&gt; 將按預期工作。 ## 魔法屬性 magic `cython`模塊提供了特殊裝飾器,可用于在 Python 文件中添加靜態類型,同時被解釋器忽略。 此選項將`cython`模塊依賴項添加到原始代碼,但不需要維護補充`.pxd`文件。 Cython 提供了這個模塊的虛假版本 &lt;cite&gt;Cython.Shadow&lt;/cite&gt; ,當安裝 Cython 時可以作為 &lt;cite&gt;cython.py&lt;/cite&gt; 使用,但是當 Cython 是 Cython 時可以被復制以供其他模塊使用。未安裝。 ### “編譯”開關 * `compiled`是一個特殊變量,在編譯器運行時設置為`True`,在解釋器中設置為`False`。因此,代碼 ```py import cython if cython.compiled: print("Yep, I'm compiled.") else: print("Just a lowly interpreted script.") ``` 根據代碼是作為編譯擴展名(`.so` / `.pyd`)模塊還是普通`.py`文件執行,將表現不同。 ### 靜態打字 * `cython.declare`在當前作用域中聲明一個類型變量,可用于代替`cdef type var [= value]`構造。這有兩種形式,第一種作為賦值(在解釋模式中創建聲明時很有用): ```py import cython x = cython.declare(cython.int) # cdef int x y = cython.declare(cython.double, 0.57721) # cdef double y = 0.57721 ``` 和第二種模式作為一個簡單的函數調用: ```py import cython cython.declare(x=cython.int, y=cython.double) # cdef int x; cdef double y ``` 它還可以用于定義擴展類型 private,readonly 和 public 屬性: ```py import cython @cython.cclass class A: cython.declare(a=cython.int, b=cython.int) c = cython.declare(cython.int, visibility='public') d = cython.declare(cython.int) # private by default. e = cython.declare(cython.int, visibility='readonly') def __init__(self, a, b, c, d=5, e=3): self.a = a self.b = b self.c = c self.d = d self.e = e ``` * `@cython.locals`是一個裝飾器,用于指定函數體中局部變量的類型(包括參數): ```py import cython @cython.locals(a=cython.long, b=cython.long, n=cython.longlong) def foo(a, b, x, y): n = a * b # ... ``` * `@cython.returns(&lt;type&gt;)`指定函數的返回類型。 * `@cython.exceptval(value=None, *, check=False)`指定函數的異常返回值和異常檢查語義,如下所示: ```py @exceptval(-1) # cdef int func() except -1: @exceptval(-1, check=False) # cdef int func() except -1: @exceptval(check=True) # cdef int func() except *: @exceptval(-1, check=True) # cdef int func() except? -1: ``` * Python 注釋可用于聲明參數類型,如以下示例所示。為避免與其他類型的注釋使用沖突,可以使用指令`annotation_typing=False`禁用此功能。 ```py import cython def func(foo: dict, bar: cython.int) -&gt; tuple: foo["hello world"] = 3 + bar return foo, 5 ``` 對于非 Python 返回類型,這可以與`@cython.exceptval()`裝飾器結合使用: ```py import cython @cython.exceptval(-1) def func(x: cython.int) -&gt; cython.int: if x &lt; 0: raise ValueError("need integer &gt;= 0") return x + 1 ``` 從版本 0.27 開始,Cython 還支持 [PEP 526](https://www.python.org/dev/peps/pep-0526/) 中定義的變量注釋。這允許以 Python 3.6 兼容的方式聲明變量類型,如下所示: ```py import cython def func(): # Cython types are evaluated as for cdef declarations x: cython.int # cdef int x y: cython.double = 0.57721 # cdef double y = 0.57721 z: cython.float = 0.57721 # cdef float z = 0.57721 # Python types shadow Cython types for compatibility reasons a: float = 0.54321 # cdef double a = 0.54321 b: int = 5 # cdef object b = 5 c: long = 6 # cdef object c = 6 pass @cython.cclass class A: a: cython.int b: cython.int def __init__(self, b=0): self.a = 3 self.b = b ``` 目前無法表達對象屬性的可見性。 ### C 類型 Cython 模塊內置了許多類型。它提供所有標準 C 類型,即`char`,`short`,`int`,`long`,`longlong`以及它們的無符號版本`uchar`,`ushort`,`uint`,`ulong`, `ulonglong`。特殊的`bint`類型用于 C 布爾值,`Py_ssize_t`用于(容器)的(簽名)大小。 對于每種類型,都有指針類型`p_int`,`pp_int`等,在解釋模式下最多三級,在編譯模式下無限深。可以使用`cython.pointer(cython.int)`構建更多指針類型,將數組構造為`cython.int[10]`。有限的嘗試是模擬這些更復雜的類型,但只能通過 Python 語言完成。 Python 類型 int,long 和 bool 分別被解釋為 C `int`,`long`和`bint`。此外,可以使用 Python 內置類型`list`,`dict`,`tuple`等,以及任何用戶定義的類型。 鍵入的 C 元組可以聲明為 C 類型的元組。 ### 擴展類型和 cdef 函數 * 類裝飾器`@cython.cclass`創建`cdef class`。 * 函數/方法裝飾器`@cython.cfunc`創建 [`cdef`](../userguide/language_basics.html#cdef) 函數。 * `@cython.ccall`創建 [`cpdef`](../userguide/language_basics.html#cpdef) 函數,即 Cython 代碼可以在 C 級調用的函數。 * `@cython.locals`聲明局部變量(見上文)。它還可用于聲明參數的類型,即簽名中使用的局部變量。 * `@cython.inline`相當于 C `inline`修飾符。 * `@cython.final`通過阻止將類型用作基類來終止繼承鏈,或者通過在子類型中重寫方法來終止繼承鏈。這可以實現某些優化,例如內聯方法調用。 以下是 [`cdef`](../userguide/language_basics.html#cdef) 功能的示例: ```py @cython.cfunc @cython.returns(cython.bint) @cython.locals(a=cython.int, b=cython.int) def c_compare(a,b): return a == b ``` ### 進一步的 Cython 函數和聲明 * `address`用于代替`&`運算符: ```py cython.declare(x=cython.int, x_ptr=cython.p_int) x_ptr = cython.address(x) ``` * `sizeof`模擬運算符的&lt;cite&gt;大小。它可以采用兩種類型和表達方式。&lt;/cite&gt; ```py cython.declare(n=cython.longlong) print(cython.sizeof(cython.longlong)) print(cython.sizeof(n)) ``` * `struct`可用于創建結構類型: ```py MyStruct = cython.struct(x=cython.int, y=cython.int, data=cython.double) a = cython.declare(MyStruct) ``` 相當于代碼: ```py cdef struct MyStruct: int x int y double data cdef MyStruct a ``` * `union`使用與`struct`完全相同的語法創建聯合類型。 * `typedef`定義給定名稱下的類型: ```py T = cython.typedef(cython.p_int) # ctypedef int* T ``` * `cast`將(不安全地)重新解釋表達式類型。 `cython.cast(T, t)`相當于`&lt;T&gt;t`。第一個屬性必須是類型,第二個屬性是要轉換的表達式。指定可選關鍵字參數`typecheck=True`具有`&lt;T?&gt;t`的語義。 ```py t1 = cython.cast(T, t) t2 = cython.cast(T, t, typecheck=True) ``` ### .pxd 特殊的 &lt;cite&gt;cython&lt;/cite&gt; 模塊也可以在擴充`.pxd`文件中導入和使用。例如,以下 Python 文件`dostuff.py`: ```py def dostuff(n): t = 0 for i in range(n): t += i return t ``` 可以使用以下`.pxd`文件`dostuff.pxd`進行擴充: ```py import cython @cython.locals(t=cython.int, i=cython.int) cpdef int dostuff(int n) ``` `cython.declare()`函數可用于在擴充`.pxd`文件中指定全局變量的類型。 ## 提示與技巧 ### 調用 C 函數 通常,不可能在純 Python 模式下調用 C 函數,因為在普通(未編譯)Python 中沒有通用的方法來支持它。但是,在存在等效 Python 函數的情況下,可以通過將 C 函數強制與條件導入相結合來實現,如下所示: ```py # mymodule.pxd # declare a C function as "cpdef" to export it to the module cdef extern from "math.h": cpdef double sin(double x) ``` ```py # mymodule.py import cython # override with Python import if not in compiled code if not cython.compiled: from math import sin # calls sin() from math.h when compiled with Cython and math.sin() in Python print(sin(0)) ``` 請注意,“sin”函數將在此處顯示在“mymodule”的模塊命名空間中(即,將存在`mymodule.sin()`函數)。您可以根據 Python 慣例將其標記為內部名稱,方法是將其重命名為`.pxd`文件中的“_sin”,如下所示: ```py cdef extern from "math.h": cpdef double _sin "sin" (double x) ``` 然后,您還可以將 Python 導入更改為`from math import sin as _sin`以使名稱再次匹配。 ### 將 C 數組用于固定大小的列表 C 數組可以自動強制轉換為 Python 列表或元組。這可以被利用來在編譯時用 C 數組替換 Python 代碼中的固定大小的 Python 列表。一個例子: ```py import cython @cython.locals(counts=cython.int[10], digit=cython.int) def count_digits(digits): """ >>> digits = '01112222333334445667788899' >>> count_digits(map(int, digits)) [1, 3, 4, 5, 3, 1, 2, 2, 3, 2] """ counts = [0] * 10 for digit in digits: assert 0 <= digit <= 9 counts[digit] += 1 return counts ``` 在普通的 Python 中,這將使用 Python 列表來收集計數,而 Cython 將生成使用 C int 的 C 數組的 C 代碼。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看