<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 融合類型(模板) > 原文: [http://docs.cython.org/en/latest/src/userguide/fusedtypes.html](http://docs.cython.org/en/latest/src/userguide/fusedtypes.html) 融合類型允許您有一個可以引用多種類型的類型定義。這允許您編寫一個靜態類型的 cython 算法,該算法可以對多種類型的值進行操作。因此,融合類型允許[泛型編程](https://en.wikipedia.org/wiki/Generic_programming),類似于 C ++中的模板或 Java / C#等語言中的泛型。 注意 目前不支持融合類型作為擴展類型的屬性。只能使用融合類型聲明變量和函數/方法參數。 ## 快速入門 ```py from __future__ import print_function ctypedef fused char_or_float: char float cpdef char_or_float plus_one(char_or_float var): return var + 1 def show_me(): cdef: char a = 127 float b = 127 print('char', plus_one(a)) print('float', plus_one(b)) ``` 這給出了: ```py >>> show_me() char -128 float 128.0 ``` `plus_one(a)`將“融合型”`char_or_float`“專門化”為`char`,而`plus_one(b)`將`char_or_float`專門化為`float`。 ## 聲明熔斷類型 融合類型可以聲明如下: ```py cimport cython ctypedef fused my_fused_type: cython.int cython.double ``` 這聲明了一個名為`my_fused_type`的新類型,它可以是和`int` _ 或 _ a `double`。或者,聲明可以寫成: ```py my_fused_type = cython.fused_type(cython.int, cython.float) ``` 只有名稱可用于組成類型,但它們可以是任何(非融合)類型,包括 typedef。即可以寫: ```py ctypedef double my_double my_fused_type = cython.fused_type(cython.int, my_double) ``` ## 使用融合類型 融合類型可用于聲明函數或方法的參數: ```py cdef cfunc(my_fused_type arg): return arg + 1 ``` 如果在參數列表中多次使用相同的融合類型,則融合類型的每個特化必須相同: ```py cdef cfunc(my_fused_type arg1, my_fused_type arg2): return cython.typeof(arg1) == cython.typeof(arg2) ``` 在這種情況下,兩個參數的類型都是 int 或 double(根據前面的示例)。但是,因為這些參數使用相同的融合類型`my_fused_type`,所以`arg1`和`arg2`都專用于相同類型。因此,對于每個可能的有效調用,此函數都返回 True。但是你可以混合融合類型: ```py def func(A x, B y): ... ``` 其中`A`和`B`是不同的融合類型。這將為`A`和`B`中包含的所有類型組合生成專門的代碼路徑。 ### 融合類型和數組 請注意,僅數字類型的特化可能不是非常有用,因為通常可以依賴于類型的提升。但是,對于內存的數組,指針和類型化視圖,情況并非如此。的確,有人可能寫道: ```py def myfunc(A[:, :] x): ... # and cdef otherfunc(A *x): ... ``` 請注意,在 Cython 0.20.x 及更早版本中,當類型簽名中的多個內存視圖使用融合類型時,編譯器會生成所有類型組合的完整交叉積。 ```py def myfunc(A[:] a, A[:] b): # a and b had independent item types in Cython 0.20.x and earlier. ... ``` 這對于大多數用戶來說是出乎意料的,不太可能是期望的,并且與其他結構化類型聲明(例如融合類型的 C 數組)不一致,這些聲明被認為是相同的類型。因此在 Cython 0.21 中進行了更改,以便對融合類型的所有內存視圖使用相同的類型。為了獲得原始行為,只需在不同的名稱下聲明相同的融合類型,然后在聲明中使用它們: ```py ctypedef fused A: int long ctypedef fused B: int long def myfunc(A[:] a, B[:] b): # a and b are independent types here and may have different item types ... ``` 要在較舊的 Cython 版本(0.21 之前版本)中僅獲得相同類型,可以使用`ctypedef`: ```py ctypedef A[:] A_1d def myfunc(A_1d a, A_1d b): # a and b have identical item types here, also in older Cython versions ... ``` ## 選擇專業化 您可以通過兩種方式選擇特化(具有特定或專用(即非融合)參數類型的函數實例):通過索引或通過調用。 ### 索引 您可以使用類型索引函數以獲得某些特化,即: ```py cfunc[cython.p_double](p1, p2) # From Cython space func[float, double](myfloat, mydouble) # From Python space func[cython.float, cython.double](myfloat, mydouble) ``` 如果使用融合類型作為基類型,這將意味著基類型是融合類型,因此基類型需要專門化: ```py cdef myfunc(A *x): ... # Specialize using int, not int * myfunc[int](myint) ``` ### 調用 也可以使用參數調用融合函數,其中自動計算調度: ```py cfunc(p1, p2) func(myfloat, mydouble) ``` 對于從 Cython 調用的`cdef`或`cpdef`函數,這意味著在編譯時計算出特化。對于`def`函數,在運行時對參數進行類型檢查,并執行盡力而為的方法來確定需要哪種特化。這意味著如果沒有找到特化,這可能會導致運行時`TypeError`。如果函數的類型未知,則`cpdef`函數的處理方式與`def`函數的處理方式相同(例如,如果它是外部的,并且沒有 cimport)。 自動調度規則通常如下所示,按優先順序排列: * 試著找到完全匹配 * 選擇最大的相應數值類型(最大浮點數,最大復數,最大 int) ## 內置熔斷類型 為方便起見,有一些內置的融合類型,它們是: ```py cython.integral # short, int, long cython.floating # float, double cython.numeric # short, int, long, float, double, float complex, double complex ``` ## 鑄造熔斷函數 融合的`cdef`和`cpdef`函數可以轉換或分配給 C 函數指針,如下所示: ```py cdef myfunc(cython.floating, cython.integral): ... # assign directly cdef object (*funcp)(float, int) funcp = myfunc funcp(f, i) # alternatively, cast it (<object (*)(float, int)> myfunc)(f, i) # This is also valid funcp = myfunc[float, int] funcp(f, i) ``` ## 類型檢查專業化 可以基于融合參數的特化來做出決定。修剪錯誤條件以避免無效代碼。可以檢查`is`,`is not`和`==`和`!=`以查看融合類型是否等于某個其他非融合類型(檢查專業化),或使用`in`和[COD5 判斷專門化是否是另一組類型(指定為融合類型)的一部分。例如: ```py ctypedef fused bunch_of_types: ... ctypedef fused string_t: cython.p_char bytes unicode cdef cython.integral myfunc(cython.integral i, bunch_of_types s): cdef int *int_pointer cdef long *long_pointer # Only one of these branches will be compiled for each specialization! if cython.integral is int: int_pointer = &i else: long_pointer = &i if bunch_of_types in string_t: print("s is a string!") ``` ## 條件 GIL 獲取/釋放 獲取和釋放 GIL 可以通過編譯時已知的條件來控制(參見 [條件獲取/釋放 GIL](external_C_code.html#gil-conditional))。 當與融合類型結合使用時,這是最有用的。融合類型函數可能必須處理 cython 本機類??型(例如 cython.int 或 cython.double)和 python 類型(例如對象或字節)。條件獲取/釋放 GIL 提供了一種運行相同代碼的方法,無論是發布 GIL(對于 cython 本機類??型)還是持有 GIL(對于 python 類型): ```py cimport cython ctypedef fused double_or_object: cython.double object def increment(double_or_object x): with nogil(double_or_object is cython.double): # Same code handles both cython.double (GIL is released) # and python object (GIL is not released). x = x + 1 return x ``` ## __signatures__ 最后,來自`def`或`cpdef`函數的函數對象具有 __signatures__ 屬性,該屬性將簽名字符串映射到實際的專用函數。這可能對檢查有用。列出的簽名字符串也可以用作融合函數的索引,但索引格式可能會在 Cython 版本之間發生變化: ```py specialized_function = fused_function["MyExtensionClass|int|float"] ``` 通常最好像這樣索引,但是: ```py specialized_function = fused_function[MyExtensionClass, int, float] ``` 雖然后者將從 Python 空間中選擇`int`和`float`的最大類型,因為它們不是類型標識符,而是內置類型。但是,通過`cython.int`和`cython.float`可以解決這個問題。 對于來自 python 空間的 memoryview 索引,我們可以執行以下操作: ```py ctypedef fused my_fused_type: int[:, ::1] float[:, ::1] def func(my_fused_type array): ... my_fused_type[cython.int[:, ::1]](myarray) ``` 使用例如同樣的方法也是如此。 `cython.numeric[:, :]`。
                  <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>

                              哎呀哎呀视频在线观看