ホームページ バックエンド開発 Python チュートリアル Typescript のような Python コードを書く

Typescript のような Python コードを書く

Aug 01, 2024 pm 08:18 PM

この記事を読みたい皆さんは、typescript が何であるかを知っていると思います。 JavaScript 開発者は、JavaScript をよりタイプセーフにするために typescript を作成しました。タイプセーフを使用すると、テストを書かなくてもコードが読みやすくなり、バグが少なくなります。 Python でタイプセーフティを実現できますか?

なぜタイプセーフティが必要なのでしょうか?

この無邪気な機能を想像してみてください

def send_email(sender, receiver, message):
    ...
ログイン後にコピー

コードの実装を意図的に隠しています。関数名とパラメータだけで、この関数が何のためのもので、この関数を使用するにはどのパラメータが必要か推測できますか?関数名から、メールを送信するための関数であることがわかります。この関数を使用するにはパラメータについてはどうすればよいですか?

最初に、送信者は電子メールの str 、受信者は電子メールの str 、メッセージは電子メールの本文の str であると推測します。

send_email(sender="john@mail.com", receiver="doe@mail.com", message="Hello doe! How are you?")
ログイン後にコピー

最も単純な推測です。しかし、それが唯一の推測ではありません。

2 番目に推測される送信者はデータベースの user_id の int、受信者はデータベースの user_id の int、メッセージはメール本文の str です。

john_user_id = 1
doe_user_id = 2
send_email(sender=1, receiver=2, message="Hello doe! How are you?")
ログイン後にコピー

アプリケーションで作業しているところを想像してみてください。ほとんどのアプリケーションは何らかのデータベースを使用します。ユーザーは通常、ID で表されます。

3 番目の推定送信者は辞書、受信者は辞書、メッセージは辞書です。

john = {
    "id": 1,
    "username": "john",
    "email": "john@mail.com"
}
doe = {
    "id": 2,
    "username": "doe",
    "email": "doe@mail.com"
}
message = {
    "title": "Greeting my friend doe",
    "body": "Hello doe! How are you?"
}
send_email(sender=john, receiver=doe, message=message)
ログイン後にコピー

send_email には電子メールとユーザー ID 以外のものが必要になる可能性があります。各パラメータにさらにデータを追加するには、辞書構造が使用されます。このメッセージは単なる str ではなく、おそらくタイトルと本文が必要であることに気づきました。

4 番目の推測では、送信者はクラス User、受信者はクラス User、メッセージは辞書です。

class User():

    def __init__(self, id, username, email):
        self.id = id
        self.username = username
        self.email = email

john = User(id=1, username="john", email="john@mail.com")
doe = User(id=2, username="doe", email="doe@mail.com")
message = {
    "title": "Greeting my friend doe",
    "body": "Hello doe! How are you?"
}
send_email(sender=john, receiver=doe, message=message)
ログイン後にコピー

send_email は、Django ORM や Sqlalchemy などのデータベース Orm と統合される可能性があります。エンドユーザーにとって使いやすいように、ORM クラスを直接使用しています。

それで、正しい答えはどれですか?そのうちの 1 つが正解になる可能性があります。おそらく、正解は 2 つの推測の組み合わせである可能性があります。送信者と受信者はクラス User (4 番目の推測) ですが、メッセージと同様に str (最初の推測) です。コード実装を読まないとわかりません。あなたがエンドユーザーであれば、これは時間の無駄です。この関数を使用するエンドユーザーとして必要なのは、関数が何を行うのか、必要なパラメーターと関数の出力が何かだけです。

解決策

ドキュメント文字列

Python には、docstring を使用した関数ドキュメントが組み込まれています。ここに docstring の例があります。

def add(x, y):
    """Add two number

    Parameter:\n
    x -- int\n
    y -- int\n

    Return: int
    """
    return x + y

def send_email(sender, receiver, message):
    """Send email from sender to receiver

    Parameter:\n
    sender -- email sender, class User\n
    receiver -- email receiver, class User\n
    message -- body of the email, dictionary (ex: {"title": "some title", "body": "email body"}\n

    Return: None
    """
    ...
ログイン後にコピー

docstring の優れた点は、エディターと互換性があることです。 vscode では、関数の上にマウスを置くと docstring が表示されます。 Python のほとんどのライブラリは、関数を文書化するために docstring を使用します。

Writing Python code like Typescript

docstring の問題はドキュメントの同期です。 docstring がコード実装と常に同期していることを確認する方法。正しくテストすることはできません。インターネット上のランダムな人から、「古いドキュメントがあることは、ドキュメントがないことよりも悪いです。」

ドクターテスト

ところで、doctest を使用して docstring をテストできます。 doctest は、docstring でサンプルを実行して、docstring をテストします。 Doctest はすでに Python にプリインストールされているため、外部の依存関係は必要ありません。この例を見てみましょう。my_math.py という名前の新しいファイルを作成し、このコードを配置します。

# my_math.py
def add(x, y):
    """Add two integer

    Parameter:\n
    x -- int\n
    y -- int\n

    Return: int
    >>> add(1, 2)
    3
    """
    return x + y


if __name__ == "__main__":
    import doctest

    doctest.testmod()

ログイン後にコピー

これは docstring のサンプルと同じコードですが、コードの最後の行に example と doctest を追加しています。 docstring をテストするには、ファイル python my_math.py を実行するだけです。出力がない場合は、例がテストに合格したことを意味します。出力を確認したい場合は、冗長モード python my_math.py -v で実行すると、この出力が表示されます。

Trying:
    add(1, 2)
Expecting:
    3
ok
1 items had no tests:
    __main__
1 items passed all tests:
   1 tests in __main__.add
1 tests in 2 items.
1 passed and 0 failed.
Test passed
ログイン後にコピー

コード例を間違えるとエラーが返されます。

# my_math.py
def add(x, y):
    """Add two integer

    Parameter:\n
    x -- int\n
    y -- int\n

    Return: int
    >>> add(2, 2) # <-- I change it here
    3
    """
    return x + y


if __name__ == "__main__":
    import doctest

    doctest.testmod()

ログイン後にコピー

出力:

**********************************************************************
File "~/typescript-in-python/my_math.py", line 12, in __main__.add
Failed example:
    add(2, 2) # <-- I change it here
Expected:
    3
Got:
    4
**********************************************************************
1 items had failures:
   1 of   1 in __main__.add
***Test Failed*** 1 failures.
ログイン後にコピー

すごいですね!これで、docstring をテストできるようになりました。ただし、注意点は次のとおりです:

  1. doctest はサンプルのみをチェックします コメント関数のパラメータはチェックせず、戻り値を返します
  2. doctest は他のテスト ツールと同様にコードを実行する必要があります。それが正しいかどうかを確認するには、doctest はコード例を実行する必要があります。コードにデータベースや SMTP サーバー (電子メールの送信など) などの外部ツールが必要な場合、doctest を使用してテストするのは困難です。

Python の入力

コードが正しいかどうかを確認するためにコードを実行する必要がない場合もあります。必要なのは入力タイプと出力タイプだけです。どうやって?この例を考えてみましょう。

def add(x, y):
    """Add two integer

    Parameter:\n
    x -- int\n
    y -- int\n

    Return: int
    """
    return x + y

def sub(x, y):
    """Substract two integer

    Parameter:\n
    x -- int\n
    y -- int\n

    Return: int
    """
    return x - y

a = add(2, 1)
b = add(1, 1)
c = sub(a, b)
ログイン後にコピー

関数 add は int を返し、関数 sub は入力パラメータとして 2 つの int を必要とします。追加関数からの戻り値を 2 つ使用して、上記の例のようにサブパラメータに置くとエラーになりますか?もちろん、サブ関数には int が必要であり、int も入力するためではありません。

Python 3.5 以降、Python にはタイピングと呼ばれる型が組み込まれています。入力すると、以下の例のように関数に型を追加できます。

def add(x: int, y: int) -> int:
    """Add two integer"""
    return x + y

a = add(1, 2)
ログイン後にコピー

Instead put it on your docstring you put it on the function. Typing is supported on many editor. If you use vscode you can hover on variable and it will shown it's type.
Writing Python code like Typescript

Nice now our code will have a type safety. eeehhhh not realy. If I intentionally use function incorrectlly like this.

def add(x: int, y: int) -> int:
    """Add two integer"""
    return x + y

res = add(1, [])
print(res)
ログイン後にコピー

It will show error

Traceback (most recent call last):
  File "~/typescript-in-python/main.py", line 5, in <module>
    res = add(1, [])
          ^^^^^^^^^^
  File "~/typescript-in-python/main.py", line 3, in add
    return x + y
           ~~^~~
TypeError: unsupported operand type(s) for +: 'int' and 'list'
ログイン後にコピー

But it doesn't show that you put incorrect type. Even worse if you use it like this.

def add(x: int, y: int) -> int:
    """Add two integer"""
    return x + y

res = add("hello", "world")
print(res)
ログイン後にコピー
ログイン後にコピー

It will succeed. It must be error because you put incorrect type.

helloworld
ログイン後にコピー

Why python typing doesn't have type checker by default??. Based on pep-3107 it said

Before launching into a discussion of the precise ins and outs of Python 3.0’s function annotations, let’s first talk broadly about what annotations are and are not:

  1. Function annotations, both for parameters and return values, are completely optional.
  2. Function annotations are nothing more than a way of associating arbitrary Python expressions with various parts of a function at compile-time. By itself, Python does not attach any particular meaning or significance to annotations. Left to its own, Python simply makes these expressions available as described in Accessing Function Annotations below.

The only way that annotations take on meaning is when they are interpreted by third-party libraries. ...

So in python typing is like a decorator in typescript or java it doesn't mean anything. You need third party libraries todo type checking. Let's see some library for typechecking.

Python typing + type checker

Here are libraries for typechecking in python. For example we will typecheck this wrong.py file

def add(x: int, y: int) -> int:
    """Add two integer"""
    return x + y

res = add("hello", "world")
print(res)
ログイン後にコピー
ログイン後にコピー

1.mypy

The "OG" of python type checker. To install it just using pip pip install mypy. Now let's use mypy to typecheck this file. Run mypy wrong.py. It will shown type error which is nice.

wrong.py:5: error: Argument 1 to "add" has incompatible type "str"; expected "int"  [arg-type]
wrong.py:5: error: Argument 2 to "add" has incompatible type "str"; expected "int"  [arg-type]
Found 2 errors in 1 file (checked 1 source file)
ログイン後にコピー

btw you can run mypy on entire project by using mypy ..

2.pyright

Another typechecker is pyright. It created by microsoft. It's same like mypy install through pip pip install pyright. Then run it pyright wrong.py. It will shown this error.

~/typescript-in-python/wrong.py
  ~/typescript-in-python/wrong.py:5:11 - error: Argument of type "Literal['hello']" cannot be assigned to parameter "x" of type "int" in function "add"
    "Literal['hello']" is incompatible with "int" (reportArgumentType)
  ~/typescript-in-python/wrong.py:5:20 - error: Argument of type "Literal['world']" cannot be assigned to parameter "y" of type "int" in function "add"
    "Literal['world']" is incompatible with "int" (reportArgumentType)
2 errors, 0 warnings, 0 informations
ログイン後にコピー

It said that it's more faster than mypy but I found that's not much diffrent. Maybe my code base it's to small. Also pyright implement more python standard than mypy you can see on https://microsoft.github.io/pyright/#/mypy-comparison. Personaly I prefer mypy than pyright because the error message were more readable.

3.pylyzer

Speaking of performance and speed another new python typechecker pylyzer. It's written in rust. You can install it through pip pip install pylyzer or through cargo (rust package manager) cargo install pylyzer --locked. Then run it pylyzer wrong.py. It will shown this error.

Start checking: wrong.py
Found 2 errors: wrong.py
Error[#2258]: File wrong.py, line 5, <module>.res

5 | res = add("hello", "world")
  :           -------
  :                 |- expected: Int
  :                 `- but found: {"hello"}

TypeError: the type of add::x (the 1st argument) is mismatched

Error[#2258]: File wrong.py, line 5, <module>.res

5 | res = add("hello", "world")
  :                    -------
  :                          |- expected: Int
  :                          `- but found: {"world"}

TypeError: the type of add::y (the 2nd argument) is mismatched
ログイン後にコピー

So far this is the most readable and beautiful error message. It's reminds me of rust compiler error. Speed, performance and most readable error message, I think I will choose to using pylyzer if the package already stable. The problem is at the time I write this blog, pylyzer still in beta. It can only typecheck your code base, it haven't support external depedencies.

Conclusion

Alright we successfully write python code like typescript (kinda). There is more way to using python typing module other than check simple type (str, int, bool etc). Maybe I will cover more advance type it in next blog. Maybe you guys have opinion about this, know better typechecker other then those 3, found other way to do typecheck in python or other. let me know on comment section below. As always Happy Coding.

以上がTypescript のような Python コードを書くの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Python vs. C:曲線と使いやすさの学習 Python vs. C:曲線と使いやすさの学習 Apr 19, 2025 am 12:20 AM

Pythonは学習と使用が簡単ですが、Cはより強力ですが複雑です。 1。Python構文は簡潔で初心者に適しています。動的なタイピングと自動メモリ管理により、使いやすくなりますが、ランタイムエラーを引き起こす可能性があります。 2.Cは、高性能アプリケーションに適した低レベルの制御と高度な機能を提供しますが、学習しきい値が高く、手動メモリとタイプの安全管理が必要です。

Pythonと時間:勉強時間を最大限に活用する Pythonと時間:勉強時間を最大限に活用する Apr 14, 2025 am 12:02 AM

限られた時間でPythonの学習効率を最大化するには、PythonのDateTime、時間、およびスケジュールモジュールを使用できます。 1. DateTimeモジュールは、学習時間を記録および計画するために使用されます。 2。時間モジュールは、勉強と休息の時間を設定するのに役立ちます。 3.スケジュールモジュールは、毎週の学習タスクを自動的に配置します。

Python vs. C:パフォーマンスと効率の探索 Python vs. C:パフォーマンスと効率の探索 Apr 18, 2025 am 12:20 AM

Pythonは開発効率でCよりも優れていますが、Cは実行パフォーマンスが高くなっています。 1。Pythonの簡潔な構文とリッチライブラリは、開発効率を向上させます。 2.Cのコンピレーションタイプの特性とハードウェア制御により、実行パフォーマンスが向上します。選択を行うときは、プロジェクトのニーズに基づいて開発速度と実行効率を比較検討する必要があります。

Python vs. C:重要な違​​いを理解します Python vs. C:重要な違​​いを理解します Apr 21, 2025 am 12:18 AM

PythonとCにはそれぞれ独自の利点があり、選択はプロジェクトの要件に基づいている必要があります。 1)Pythonは、簡潔な構文と動的タイピングのため、迅速な開発とデータ処理に適しています。 2)Cは、静的なタイピングと手動メモリ管理により、高性能およびシステムプログラミングに適しています。

Pythonの学習:2時間の毎日の研究で十分ですか? Pythonの学習:2時間の毎日の研究で十分ですか? Apr 18, 2025 am 12:22 AM

Pythonを1日2時間学ぶだけで十分ですか?それはあなたの目標と学習方法に依存します。 1)明確な学習計画を策定し、2)適切な学習リソースと方法を選択します。3)実践的な実践とレビューとレビューと統合を練習および統合し、統合すると、この期間中にPythonの基本的な知識と高度な機能を徐々に習得できます。

Python Standard Libraryの一部はどれですか:リストまたは配列はどれですか? Python Standard Libraryの一部はどれですか:リストまたは配列はどれですか? Apr 27, 2025 am 12:03 AM

PythonListSarePartOfThestAndardarenot.liestareBuilting-in、versatile、forStoringCollectionsのpythonlistarepart。

Python:自動化、スクリプト、およびタスク管理 Python:自動化、スクリプト、およびタスク管理 Apr 16, 2025 am 12:14 AM

Pythonは、自動化、スクリプト、およびタスク管理に優れています。 1)自動化:OSやShutilなどの標準ライブラリを介してファイルバックアップが実現されます。 2)スクリプトの書き込み:Psutilライブラリを使用してシステムリソースを監視します。 3)タスク管理:スケジュールライブラリを使用してタスクをスケジュールします。 Pythonの使いやすさと豊富なライブラリサポートにより、これらの分野で優先ツールになります。

Web開発用のPython:主要なアプリケーション Web開発用のPython:主要なアプリケーション Apr 18, 2025 am 12:20 AM

Web開発におけるPythonの主要なアプリケーションには、DjangoおよびFlaskフレームワークの使用、API開発、データ分析と視覚化、機械学習とAI、およびパフォーマンスの最適化が含まれます。 1。DjangoandFlask Framework:Djangoは、複雑な用途の迅速な発展に適しており、Flaskは小規模または高度にカスタマイズされたプロジェクトに適しています。 2。API開発:フラスコまたはdjangorestFrameworkを使用して、Restfulapiを構築します。 3。データ分析と視覚化:Pythonを使用してデータを処理し、Webインターフェイスを介して表示します。 4。機械学習とAI:Pythonは、インテリジェントWebアプリケーションを構築するために使用されます。 5。パフォーマンスの最適化:非同期プログラミング、キャッシュ、コードを通じて最適化

See all articles