私は最近、Typescript の関数の注釈についてブログを投稿しました。少し勉強を終えて、Python で関数にアノテーションを付ける方法についてさらに理解しました。このブログでは、前回のブログと同様の例を使用して、Python 関数にアノテーションを付けることについて説明していきます。
Visual Studio Code で python.analysis.typeCheckingMode を Basic、standard、strict のいずれかに設定することで、型の注釈を検証できます。 Basic オプションと Standard オプションでは、必ずしも関数や変数に注釈を付ける必要はありませんが、strict オプションでは必ず注釈を付けます。
ショックを受けるかもしれません しかし、Python では関数を返したり、関数を値として渡すことができます。コールバック関数は、実際には次のように記述される Callable 型を使用して注釈が付けられます。
Callable[[argtype1, argtype2, argtype3], returnType]
たとえば、関数 length(text: str) -> int には Callable[[str], int]
という注釈が付けられます例:
JavaScript のこの関数
function multiplier(factor){ return value => factor * value } const n = multiplier(6) n(8) // 48
Python では次のように記述できます
def multiplier(factor): def inner(value): return value * factor return inner n = multiplier(6) n(8) #48
次のように、(文字通り) int と float の両方の Union である、number という TypeAlias を作成できます。
from typing import TypeAlias, Union number: TypeAlias = Union[int, float]
パラメータを JavaScript の数値 としてアプローチします。
したがって、この関数に注釈を付けるには、
def multiplier(factor: number) -> Callable[[number], number]: def inner(value: number) -> inner: return value * factor return inner a = multiplier(4.5) a(3) #13.5
古典的なジェネリック関数の例は次のとおりです
def pick(array, index): return array[index] pick([1,2,3], 2) #3
TypeVar を使用して、一般的な冗長 (typescript よりも冗長です) を作成できるようになりました。
from typing import TypeVar T = TypeVar("T") # the argument and the name of the variable should be the same
それで、
from typing import TypeVar, Sequence def pick(array: Sequence[T], index: int) -> T: return array[index] print(pick([1,2,3,4], 2))
それでは、JavaScript でマップのように動作するカスタム myMap 関数はどうでしょうか。そのようなものです;
覚えておいてください: Python の map() は List 型ではなく Iterable 型を返します
def myMap(array, fn): return map(fn, array) def twice(n): return n * 2 print(myMap([1,2,3], twice))
Callable 型と TypeVar 型を組み合わせて使用して、この関数に注釈を付けることができます。 観察してください...
from typing import TypeVar, Iterable, Callable Input = TypeVar("Input") # Input and "Input" must be the same Output = TypeVar("Output") def myMap(array: Iterable[Input], fn: Callable[[Input], Output]) -> Iterable[Output]: return map(fn, array) def twice(n: int) -> int: return n * 2 print(myMap([1,2,3], twice))
または、呼び出し可能な関数にエイリアスを付けることもできます
from typing import TypeVar, Iterable, Callable Input = TypeVar("Input") Output = TypeVar("Output") MappableFunction = Callable[[Input], Output] def myMap(array: Iterable[Input], fn: MappableFunction[Input, Output]) -> Iterable[Output]: return map(fn, array)
MappableFunction がこれらのジェネリック型の入力と出力を受け取り、それらを Callable[[Input], Output] のコンテキストに適用することに注目してください。
myFilter 関数にどのように注釈が付けられるかを少し考えてください?
そう思いましたか?
from typing import Iterable, TypeVar, Callable Input = TypeVar("Input") def myFilter(array: Iterable[Input], fn: Callable[[Input], bool]) -> Iterable[Input]: return filter(fn, array)
その通りです
クラスのアノテーションについて話すべきではないことは承知していますが、ジェネリック クラスについて説明する時間をください。
あなたが Typescript の出身なら、これがそれらを定義する方法です
class GenericStore<Type>{ stores: Array<Type> = [] constructor(){ this.stores = [] } add(item: Type){ this.stores.push(item) } } const g1 = new GenericStore<string>(); //g1.stores: Array<string> g1.add("Hello") //only string are allowed
しかし、Python ではそれらはかなり異なり、扱いにくいです。
この GenericStore クラスを Python で再作成するには
Callable[[argtype1, argtype2, argtype3], returnType]
前のブログで述べたように、これはよりスマートな型システムの構築に役立ち、バグの可能性が減ります (特に mypy のような静的ファイル チェッカーを使用する場合)。また、堅牢な型システムを使用してライブラリ ( または SDK) を作成する場合、そのライブラリを使用する開発者の生産性が大幅に向上します (主にエディターの提案によるものです)
この文章に質問や間違いがある場合は、下のコメント欄でお気軽に共有してください ⭐
以上がPython で関数に注釈を付けるの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。