関数の戻り値の型と引数の型を知る方法は?


91

私はPythonのダックタイピングの概念を知っていますが、関数の引数のタイプや関数の戻り値のタイプに苦労することがあります。

さて、私が自分で関数を書いた場合、私はタイプを知っています。しかし、誰かが私の関数を使用して呼び出したい場合、その人はどのようにして型を知ることが期待されますか?私は通常、関数のdocstringに型情報を入れます(:"...the id argument should be an integer...""... the function will return a (string, [integer]) tuple."

しかし、docstring内の情報を検索する(そしてそれをコーダーとしてそこに置く)ことは、実際にそれが行われることになっている方法ですか?

編集:回答の大部分は「はい、文書化してください」に向けられているようですが。「複雑な」タイプの場合、これは必ずしも簡単ではないと思います。
例:関数がタプルのリストを返し、各タプルが形式(node_id、node_name、uptime_minutes)であり、要素がそれぞれ文字列、文字列、整数であることをdocstringで簡潔に説明するはどうすればよいですか?
docstring PEPのドキュメントには、そのガイドラインはありません。
その場合はクラスを使用する必要があるという反論があると思いますが、Pythonはリストとタプルを使用して、つまりクラスなしでこれらを渡すことができるため、非常に柔軟です。


2
簡単な答えは「はい」です。長い答えは「もちろんです」です。多くのPythonコードを見たことがあるかどうかはわかりませんが、実際に使用しているパッケージを示すように質問を更新する必要があります。そうすれば、ライブラリコードでどのように処理されているかを確認できるコードに誘導できます。 '現在実際に使用しています。
S.Lott 2011年

@ S.Lott:私は現在、機械化パッケージに苦労していますが、それは(残念ながら)十分に文書化されていないと思います。
Rabarberski 2011年

6
たくさんのコードをすばやく書くことができ、戻り値の型、引数の型、実行時のパフォーマンス、今後10年間スパゲッティコードを使用および維持する必要がある人などのありふれたことを心配する必要がないので、Pythonはクールです。ため息をつく。
jarmod 2013年

回答:


128

さて、2011年から状況は少し変わりました!今すぐそこだタイプのヒントあなたは注釈の引数に使用し、あなたの関数の型を返すことができますPythonの3.5インチ 例:これ:

def greeting(name):
  return 'Hello, {}'.format(name)

これで次のように書くことができます:

def greeting(name: str) -> str:
  return 'Hello, {}'.format(name)

これで型を確認できるように、ユーザーと型チェッカーがコードを調査するのに役立つ、ある種のオプションの静的型チェックがあります。

詳細については、PyCharmブロ​​グのタイプヒントに関するブログ投稿を参照することをお勧めします。


構文をヒンティングのタイプにもPythonの2.7のために提案されたことに注意してください 、ここで同じPEP-0484インチ そしてそれは少なくともv2017.3からPyCharmで動作します。
viddik13 2018

1
まったく同じ定義のグリーティング関数がint型のオブジェクトを返す場合、エラーは発生しません。では、戻り値の型について明示的に言及しているが、ルールに従わずに別の型のオブジェクトを返す場合、この種の型チェックの使用法は何でしょうか。
Arashsyh

3
@Arashsyh:はい、その通りです。型ヒントはPythonを静的に型付けされた言語に変換しません。適切な型を適切な方法で使用するかどうかは、あなた次第です。そして、これらのタイプのヒントは、より速く開発したり、コードを自己文書化したり、何かを台無しにしたときに警告を受け取ったりするのに役立ちます。特にPyCharm(または同様のIDE)を使用する場合、異なるタイプを使用すると警告が表示され、他のいくつかのことに役立ちます。上記の回答で提案されているブログ投稿を読むことをお勧めします。
Nerxis

これは計算が速いですか?
ブライスウェイン

18

これが動的言語の仕組みです。ただし、特にドキュメントが不十分な場合は、必ずしも良いことではありません。ドキュメントが不十分なPythonフレームワークを使用しようとした人はいますか?ソースの読み取りに戻らなければならない場合があります。

ダックタイピングの問題を回避するためのいくつかの戦略は次のとおりです。

  • 問題のあるドメインの言語を作成する
  • これは、適切な名前を付けるのに役立ちます
  • タイプを使用してドメイン言語で概念を表す
  • ドメイン言語の語彙を使用した名前関数パラメーター

また、最も重要なポイントの1つ:

  • データを可能な限りローカルに保ちます!

明確に定義され、文書化されたタイプがいくつか渡されるだけです。コードを見れば、他のことは明らかです。コードの近くを見ても理解できないような、遠くから来る奇妙なパラメータタイプはありません...

関連して(そしてdocstringにも関連して)、Pythonにはdoctests。と呼ばれるテクニックがあります。これを使用して、メソッドがどのように使用されると予想されるかを文書化します。同時に、優れた単体テストカバレッジを実現します。


1
ずんぐりしたドキュメントは、上記の回答で述べられている哲学の良い代表的な例です。
Jerry Ajay 2017

7

コーセラコースに参加し、デザインレシピを教えてもらうレッスンがありました。

docstring形式の下では、preetyが便利だと思いました。

def area(base、height):
    '' '(数値、数値)->数値#** TypeContract **
    寸法がベースのトリングの面積を返します#**説明**
    と高さ

    >>> area(10,5)#**例**
    25.0
    >>エリア(2.5,3)
    3.75
    '' '
    リターン(ベース*高さ)/ 2 

docstringがこのように書かれていれば、開発者にとって大いに役立つかもしれないと思います。

ビデオへのリンク[ビデオをご覧ください]https//www.youtube.com/watch?v = QAPg6Vb_LgI


5

はい、docstringを使用して、クラスと関数を他のプログラマーにとってより使いやすくする必要があります。

詳細:http//www.python.org/dev/peps/pep-0257/#what-is-a-docstring

一部のエディターでは、入力中にdocstringを表示できるため、作業が非常に簡単になります。


+1:それを文書化してください。それが唯一の正しい方法であり、静的に型付けされた言語にも当てはまります。戻り値の型は、全体像の重要な部分ではありません。
2011年

私は私のタイプが好きですありがとうございます。ドキュメント+タイプ=天国
masm 6419

2

はい、そうです。

Pythonでは、関数が常に同じ型の変数を返す必要はありません(ただし、関数が常に同じ型を返すと、コードが読みやすくなります)。つまり、関数に単一の戻り値の型を指定することはできません。

同様に、パラメータも常に同じタイプである必要はありません。


1

例:関数がタプルのリストを返し、各タプルが形式(node_id、node_name、uptime_minutes)であり、要素がそれぞれ文字列、文字列、整数であることをdocstringで簡潔に説明するにはどうすればよいですか?

ええと...これについての「簡潔な」説明はありません。複雑です。あなたはそれを複雑になるように設計しました。また、docstringに複雑なドキュメントが必要です。

申し訳ありませんが、複雑さは-まあ-複雑です。


3
OK。オフトピック(一種):しかし、よりクリーンなデザインは何でしょうか?クラス?
Rabarberski 2011年

@Rabarberski:必ずしもそうとは限りません。ここでは複雑さが避けられないように聞こえます。簡潔であることが常に達成可能であるとは限らず、望ましいとは限りません。
S.Lott 2011年

1
この種のことを文書化する明白な方法は、list <tuple <int、str、int >>のようにJavaジェネリックに似たものを使用することです。しかし、良くも悪くも、それはPythonの方法ではありません。
スカイラー2012


0

Docstrings(および一般的なドキュメント)。Python 3では、PEP 3107で説明されているように、(オプションの)関数アノテーションが導入されています(ただし、docstringを省略しないでください)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.