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

この記事を読みたい皆さんは、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) # 



<p>出力:<br>
</p>

<pre class="brush:php;toolbar:false">**********************************************************************
File "~/typescript-in-python/my_math.py", line 12, in __main__.add
Failed example:
    add(2, 2) # 



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

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

<h3>
  
  
  Python の入力
</h3>

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

<pre class="brush:php;toolbar:false">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'
</module>

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

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 までご連絡ください。
LinuxターミナルでPythonバージョンを表示するときに発生する権限の問題を解決する方法は?LinuxターミナルでPythonバージョンを表示するときに発生する権限の問題を解決する方法は?Apr 01, 2025 pm 05:09 PM

LinuxターミナルでPythonバージョンを表示する際の許可の問題の解決策PythonターミナルでPythonバージョンを表示しようとするとき、Pythonを入力してください...

HTMLを解析するために美しいスープを使用するにはどうすればよいですか?HTMLを解析するために美しいスープを使用するにはどうすればよいですか?Mar 10, 2025 pm 06:54 PM

この記事では、Pythonライブラリである美しいスープを使用してHTMLを解析する方法について説明します。 find()、find_all()、select()、およびget_text()などの一般的な方法は、データ抽出、多様なHTML構造とエラーの処理、および代替案(SEL

TensorflowまたはPytorchで深い学習を実行する方法は?TensorflowまたはPytorchで深い学習を実行する方法は?Mar 10, 2025 pm 06:52 PM

この記事では、深い学習のためにTensorflowとPytorchを比較しています。 関連する手順、データの準備、モデルの構築、トレーニング、評価、展開について詳しく説明しています。 特に計算グラップに関して、フレームワーク間の重要な違い

あるデータフレームの列全体を、Python内の異なる構造を持つ別のデータフレームに効率的にコピーする方法は?あるデータフレームの列全体を、Python内の異なる構造を持つ別のデータフレームに効率的にコピーする方法は?Apr 01, 2025 pm 11:15 PM

PythonのPandasライブラリを使用する場合、異なる構造を持つ2つのデータフレーム間で列全体をコピーする方法は一般的な問題です。 2つのデータがあるとします...

人気のあるPythonライブラリとその用途は何ですか?人気のあるPythonライブラリとその用途は何ですか?Mar 21, 2025 pm 06:46 PM

この記事では、numpy、pandas、matplotlib、scikit-learn、tensorflow、django、flask、and requestsなどの人気のあるPythonライブラリについて説明し、科学的コンピューティング、データ分析、視覚化、機械学習、Web開発、Hの使用について説明します。

Pythonでコマンドラインインターフェイス(CLI)を作成する方法は?Pythonでコマンドラインインターフェイス(CLI)を作成する方法は?Mar 10, 2025 pm 06:48 PM

この記事では、コマンドラインインターフェイス(CLI)の構築に関するPython開発者をガイドします。 Typer、Click、Argparseなどのライブラリを使用して、入力/出力の処理を強調し、CLIの使いやすさを改善するためのユーザーフレンドリーな設計パターンを促進することを詳述しています。

Pythonの仮想環境の目的を説明してください。Pythonの仮想環境の目的を説明してください。Mar 19, 2025 pm 02:27 PM

この記事では、Pythonにおける仮想環境の役割について説明し、プロジェクトの依存関係の管理と競合の回避に焦点を当てています。プロジェクト管理の改善と依存関係の問題を減らすための作成、アクティベーション、およびメリットを詳しく説明しています。

正規表現とは何ですか?正規表現とは何ですか?Mar 20, 2025 pm 06:25 PM

正規表現は、プログラミングにおけるパターンマッチングとテキスト操作のための強力なツールであり、さまざまなアプリケーションにわたるテキスト処理の効率を高めます。

See all articles

ホット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衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境