私の現在の会社と私が取り組んでいるオープンソースプロジェクトの両方で、私はどこを見ても同じ凶悪なアンチパターンを見続けています。
def foo(params):
why_wasnt_this_an_argument = params['why_wasnt_this_an_argument']
# do something
print('kill me')
これらの関数は、特定の/明確な引数を取る代わりに、主がその中身をparams知っているという不思議な辞書を取ります。まるで、関数を書いている間、関数が何をするのかさえ知らなかったようです。この関数が何をしているのかをどうやって知るのですか?この関数のテストをどのように作成する必要がありますか?私はparams、これらの神に見捨てられた機能を使用またはテストできるように、何が含まれているのかを理解するために数十時間を費やしました。
これは、他の人がおそらくあなたのコードを読まなければならないことを思い出させるものです。何にも名前を付けないでくださいparams。また、引数として定義が不適切な辞書を使用して関数を定義しないでください。
これは、** kwargsが意図していることを正確に実行するために使用されます。
レベル2
auntanniesalligator158ポイント・4日前
ええ、ここでの問題は、パラメータに含める必要のあるキーと値を文書化していないことです。また、同じ柔軟性が** kwargsでより適切に処理されるように思われますが、それは、プログラマーが特定である必要がある場合に期待される引数と値をリストすることを気にしないという問題を解決しません。
レベル3
matplotlibで泣く
レベル4
デザイナー:「ドキュメントを読むだけ」
ドキュメント:「KWARGS」
レベル5
inconspicuous_male45ポイント・3日前
公平を期すために、Matplotlibは私が使用した中で最も文書化されたPythonライブラリの1つですが、必要なものを見つけるために数十ページを掘り下げる必要があります。
レベル6
ええ、でもそれはある言語の言語です。かなり長い間それで働いたが、それでもそれが初日だったようにグーグルのもの。可能な場合はいつでも型付き言語に戻り、Pythonで型アノテーションを幅広く使用します。人々は、言語があなたをサポートするためのツールであり、誰も戦うべきではないことを理解する必要があります。Matplotlibはまさにこれを行っています。
レベル7
Matplotlibは間違いなく、それを学ぶために費やした時間の点で私にとってより悪いリターンを持っているツールです。私はそれを3年間使って、何話かわからないのを聞いたり、ドキュメントを読んだりしました。頭にくっつかないだけです。私は理論を知っていますが、それを私にとって直感的なものに簡単に翻訳することはできません。
レベル8
Seabornとmlxtendに引っ越しました。MatPlotLibについて考えるのは嫌いです。
レベル9
個人的にボケ味が大きい
レベル6
それはそれが十分に文書化されていないことを意味します
レベル7
その詳細に文書化されています。それを使用する経験は常に正方形のものから始めるように感じるということだけです。あまり書かれていないグラフィックライブラリは大きな仕事だとは言いたくありませんが、MPLの1つのことは、MPLの他のことを理解するのに役立たないようです。
Rには、インスタンスの場合、その関数の十分に文書化された引数によって制御される一般的な統計プロットごとに関数があり、すべて同じパターンを使用します。線を引きたい場合は、それを行う関数があります。
MPLには、明確に文書化された引数、いくつかの不十分に文書化されたクワーグ、および補助関数の組み合わせによって制御される一般的な統計プロットの関数があり、確立パターンに従わないことがよくあります。線を引きたい場合は、そのための別のライブラリがあります。
レベル7
さて、少し掘り下げた後、あなたは実際に答えを見つけて、何かを使う方法を理解するでしょう。十分に文書化されていない言語とは、ドキュメントだけから実際にその使用方法を学ぶことができない言語です。
10,000ページの完全な取扱説明書があるものは十分に文書化されています。「自己文書化」であると主張する主要な機能に関するパンフレットを備えた同様の複雑さのライブラリは、
レベル8
fatterSurfer22点・3日前
ドキュメントの品質はその完全性に直交していると私は主張します-言い換えれば、matplotlibは十分に文書化されていますが不十分です
レベル9
よ、この直交する話はどうしたの?物理学の私のバックグラウンドから、それは私には日中の意味があることは明らかです、私はそれがなぜ使用されているのか/プログラミングの観点からどこから来ているのか分かりません、そしてこれは私がそれを見たのは2回目です
レベル10
私の経験では、これは開発者の間で非常に一般的な言い回しです。そうは言っても、私は非常に非伝統的なプログラミングのバックグラウンドを持っています(関連:私は機械工学の学位を持っており、機械工として6年間働いていました)
レベル6
そのような針の山の中の針は「最もよく文書化された」の向こう側にあります
レベル7
針の山の中から針を見つけるのは、針が入っていないプリンのボウルの中から針を見つけるよりも簡単です。
レベル8
針が入っていないプリンのボウルから針を見つける
あなたの磁石を取り出して、すぐに失敗して、家に帰ってください。
その上、針はより伝統的に干し草の山に隠されています。
レベル9
私が言いたいのは、matplotlibのドキュメントは退屈な場合に非常に役立つということです。私が使用した多くのライブラリには、何百ページものドキュメントがありますが、それらは意味がない、正しくない、あいまいすぎる、または不完全であるため、すべて完全に役に立たないものです。MPL自身のドキュメントからクラスや関数に関する情報を見つけることができなかったことがありません。クリックするだけです。
レベル4
投げ込む kwargs.update({"matlab": "stinks", "even": "more"})
編集:彼らが私に 他の 悪い ことを教えようとしたとき、私は大学以来matplotlibが大好きです
レベル5
それは…なぜあなたはそれをする必要があるのですか?それはとても悪い習慣です。本当にオプションを更新したい場合は、最初にディープコピーを実行して作業してください。
もう1つの返信
レベル4
kwargsを使用しているのは、matplotlibをサポートすることだけです。それから私はまだそれらが何であるかわからないので私はすべてのオプションをリストします。
レベル4
私は私の魂の中でそれを感じます
もう1つの返信
レベル2
確かにそれは受信側では問題ありませんが、本当に驚くべきことに、プロデュース側または呼び出し側で同様の何かを持っている必要があります。何かのようなもの:
foo({**globals(), **locals()})
レベル3
おっと、サタンを落ち着かせなさい。
レベル2
あなたはそれをどのように正確に意味するかを指定しなかったので、このコメントはそれを具体的にすることです
def FunctionFromHell(*args,**kwargs):
pass #literally anything
さらに悪いです。
それらは定義されることになっています
def F(phrase="hello there", person="general kenobi"):
print(phrase,person)
のように使用されます
kwargs={"phrase":"asta la vista","person":"baby"}
F(**kwargs)
その後、次のようなことをしても大丈夫かもしれません
def wrapper(time,kwargs_for_F):
print(time)
F(**kwargs_for_F)
レベル3
トップの後にあなたが説明したのは** kwargsではありません
開梱するだけです
技術的には** kwargsも解凍していますが、メソッド定義を参照しているという点でより具体的です
これが私の見解です:
構文規則と常識で要求されるように、最初に必須およびオプションの引数があります。
時々個々の値の束として反復可能を期待する使用時に、反復可能をよりカジュアルかつ簡単に渡したい場合の* argsがあります。印刷可能なオブジェクトを各行の入力として使用して、オブジェクトのデバッグなどのために、ある種のフォーマットで行を印刷することをお勧めします。
** kwargsの最適な使用法は、opが説明しているように、キーが予期されていない場合に理想的です。それらの優れた用途は、プログラムでcssとhtmlを作成することです。また、html要素キーを追加できます。また、例で必要とされるように、コードに100万個の名前付きパラメーターを含める必要はありません。
あまり最適ではない使用法は、実行前にパラメーター名を推測する可能性がありますが、通常のパラメーターを使用するだけではない場合は考えられません。存在しない値(キーなし)、なしの値を区別したい場合は、 、None値ではなく、それを使用する必要がありますが、それはたわごととしてハッキーに聞こえます
レベル4
反復可能オブジェクトをよりカジュアルに渡したい場合の* argsがあります
確かに、それは大丈夫です。
つまり、意図的に* argsを使用し、それを非常に具体的な入力のリストとして扱う人もいます。このような:
args=(1,0,"peter") #except they never show you this as an example,
#you're just left with this:
def stuff(*args):
return args[0]/1, args[1]+1, args[2][1:2]
それらの優れた用途は、プログラムでcssとhtmlを作成することです。
私は同意しますが、実際にはhtml標準によって文書化されています。それへの簡単なリンクと、関数がどのように機能するかは明らかです。
レベル5
#except they never show you this as an example,
このちょっとしたたわごとを投稿する前に、コンテンツの警告が必要です
レベル3
まさにこれ。関数に受け入れ可能なパラメーターの固定セットがある場合は、それらをで指定しますdef。関数がパラメータの固定セットを持つことができない場合、それはある種の一般的なメタプログラミングweirdo構造であるため、を使用しても問題ありません**kwargs。しかし、その時だけ。
レベル2
これは双方向であり、特に* argsと組み合わせると、読者をさらに混乱させる可能性が非常に高くなります。それでも、すべての引数を渡すことによって関数を変更するのに役立ちます。これを行うことが役立つ場合もありますが、それに関するドキュメントをまっすぐに保つために多くの注意を払う必要があります。
私はちょうど望みました、いくつかのタイプ/ドキュメントのヒントがそれに続きます…あなたを見て、pycharm-しかし、ローカル構成の問題である可能性があります。私はチェックするのに十分に気になりません(私が持っているそれらの少数の、まれなパススルー関数でさえ)。
レベル2
これが私が** kwargsを使用しない理由です。
レベル3
Plague_Healer14点・3日前
** kwargsには用途がありますが、注意しないと面倒になる可能性があります。
レベル4
これは非常に多くの言語機能に当てはまります。たとえば、メタプログラミングは、それについて訓練を受けている場合に非常に効果的に使用できます。しかし、それはフットガンである可能性が高いです。** kwargsはPythonのフットガンです。これは便利な場合がありますが、全体として、コードの保守が難しくなります。
レベル5
大きな力には大きな責任が伴います。私たちのフレンドリーな近所のウェブ開発者からのアドバイス。
レベル6
私が行うすべての商用プログラミング作業では、フットガンを避けています。正しく使う方法がわからないからではなく、いつか社内の誰かが私のコードを変更しなければならず、「やあ、WTF?」と言って来てほしくないからです。
レベル7
あなたは間違いなく確かな点を持っています。
レベル2
うん** kwargsと考えられる原因はプログラマーがこの概念を理解していないことです
レベル1
boto3で泣く
レベル2
本当。例を見たり、ライブラリに対してブルートフォース攻撃を試みたりせずに、boto3で特定のことを実行する方法を理解する方法はありません。すべてが非常に一般的であるため、ライブラリを非常に単純にする一方で、ユーザーにとっては苦痛です。
レベル2
うーん、AWSスタックは一般的に悪夢です。私のPythonboto3コードの90%は例からはぎ取られていますが、私が力ずくしなければならなかったより難解な関数のいくつか。
私のお気に入りはJenkinsfileです。これは、コードがEC2にデプロイされた後、シェルスクリプトを実行してcronやその他のものを更新する必要があります。
Jenkinsfile->デプロイステップ->シェルコマンド-> AWSシステムマネージャーコマンドで、各引数は個別のJSONを取ります->-parameters引数->パラメーターJSON->コマンドdict-> bashコマンドの文字列のリスト->実行シェルスクリプト(それ自体が一連のpythonスクリプトを開始します)。
会社コードではない場合は、ここに投稿します。
レベル2
少なくともドキュメントは良いです
レベル2
正直なところ、それは型情報が不足しているPythonの弱点にすぎません。
TypescriptとRustでは、必要なものを渡しているかどうかを確認するのは簡単です。
レベル3
それでも、AWSへのそれほどひどくなくよりPythonicなAPIを思い付くことができるはずだと私は感じています。
レベル4
少年は私が大好き.filter([{'TagKey': 'Name', 'TagValue': 'foo'}])ですか。ここで使用できるキー/値データ構造があれば…
レベル5
私が何年も考えてきたこの皮肉なコメント。ありがとうございました。笑。
レベル5
私のbotoコードはすべて、その中のdict_to_boto_idiocyどこかにあるような関数で終わります。
レベル6
当店では、AWSに直感的なAPIを提供するために、実際に独自のPythonモジュールを作成しました
レベル7
共有してください、そしてヒーローになってください。
レベル8
了解しました。https://github.com/ECS-Rocks/EcsPythonModuleにアクセスします
これは、私たちのビジネスのユースケースに合わせて非常に調整されています。DynamoDBとSESを頻繁に使用するAWSLambdaで実行されているコードがたくさんない限り、おそらくそれはあまり使用されません。これは、コーディングのニーズの約90%だからです。
編集:モジュールで問題が発生した場合は問題を開き、新しい機能をモジュールに提供したい場合は、プルリクエストを送信してください。
レベル7
ここでも同じですが、asyncioの良さを表すaiohttpに基づいており、完全に型指定されています。ボトマジックに耐えられなかった。低レベルのAWSリクエストを通過すると、残りは簡単にエンコードされます。
レベル7
同じですが、紺碧です。
そして、私の会社は、Python SDKの使用はおかしなことであり、すべてをテラフォームで行うことを決定しました。
それはコミュニティです、それはすべてをすることができます!
最も単純なクラウドリソースを作成する以外に何かをしたいときはいつでも、ひざまずいているような気がします。
レベル4
え?" dynamodb_table.query(KeyConditionExpression=Key(key).eq(value))"の何が問題になっていますか?
/ s 明らかに
もう1つの返信
レベル3
それは重要ではありません。Pythonではさまざまな方法でタイプチェックを実行できますが、このように使用されるdictは必要ありません。
さらに2件の返信
レベル3
私は実際にはそれが合理的な解釈だとは思いません。
この人は、コードを読みやすくするために設計された言語機能の使用を避けるために邪魔をしませんでした。最初:パラメータ、次に2番目のkwargs。
なぜ彼らはTypescriptで(特に)詳細な型注釈を付けたと思いますか?そして、そのような人は、Rustの近くのどこにも許可されるべきではありません。彼らが作る混乱…
レベル3
人々はどんな言語でも恐ろしいコードを書くことができます。Pythonでこれをより良くする方法はたくさんあり、Rustでは次のようなひどいことをすることができます。
fn garbage(HashMap<&str, Box<Any>>)
レベル3
いいえ、ちがいます。関数パラメーターを表す型付きデータ構造を完全に自由に作成できます。NamedTupleまたはdataclassは、このために特別に設計されています。
レベル1
aton_something112ポイント・4日前
私はそれが役に立つかもしれないまれなケースを見ることができます:機能が利用可能な多くのオプションであるとき。
しかし、そのような場合は、を使用し**kwargs、詳細なdocstringを記述して、値が一貫しているかどうかを確認します。
レベル2
それはまさにkwargsが何であるかではありませんか?
レベル3
aton_something50ポイント・4日前
**kwargs関数呼び出しでのキーワード引数の解凍です。それはその使用法をオプションにし、ユーザーにこの構文を使用するように制約します:foo(param1=value1, param2=value2)これは結果として:kwargs = {param1: value1, param2, value2}
paramsOPのは、それが必須作り、位置引数ではなく、制約のタイプを行います。私はOPのfoo気まぐれfoo("bar")を呼び出すことができ、その呼び出しは合法ですが、TypeError設計が不適切であるために発生します。
レベル4
利用可能な引数が非常に多い場合は、関数の実行が多すぎるか、typing.NamedTupleやデータクラスなどのオブジェクト内にフラグをカプセル化する必要があると主張する人もいるかもしれません。
OPは特に位置的な議論ではありません。これは「位置引数またはキーワード引数」です。Python 3.8では、オプションで名前で渡すことができない「位置のみ」の引数を持つことができるため、これが区別されます。それを指摘するのは本当に気難しいですが、それでも注目に値します:)
def mean(first, second, /, *, negate):
…
MyPyのような静的型チェッカーを使用している場合(これは、経験から、コードの入力に関連する大量の論理エラーやバグを見つけるのに役立つため、一般的には良い考えです)、それでもスタブを提供する必要がありますこれらの関数はとにかく有効な署名を提供できるようにするため、ほとんどの場合、適切なパラメーターを渡すだけでもかまいません。
これにより、Pythonのモックライブラリなどのツールは、自動スペック設定時に関数のシグネチャが何であるかを認識できるようになります。これにより、実際にはテストがサイレントに完了するのではなく、何かをモックして間違ったシグネチャを提供すると、単体テストが失敗します。あなたがそれが何であると思うかをテストする:-)
レベル5
こんにちは、nekokattt。ちょっと頭を上げてください!
コードブロック/モノスペーステキストブロックにトリプルバックティック( “ `)を使用しようとしたようです。
これはredditで普遍的にサポートされていません。一部のユーザーにとって、コメントは意図したとおりに表示されません。
代わりに4つのスペースですべての行をインデントすることでこれを回避できます。
新しいRedditの「コードブロック」フォーマット機能のように、少し優れた互換性を提供する他の方法もあります。
良い一日を、ネコカット。
このコメントに「backtickopt6」と返信すると、オプトアウトできます。「backtickbbotdm5」で応答する代わりに、PMにアラートを送信するように構成します。「dmmode_end」を送信してPMModeを終了します。
レベル6
マークダウンが標準として扱われたかどうか想像してみてください…
レベル5
確かに非常にうるさいですが、本当に有益です。「位置のみ」(ただし、理由からPython 3.6を使用しています)と「必須のキーワードのみの引数」を定義できるとは知りませんでした。
レベル6
公正なこと、そして私がいくつかの新しい情報を提供してくれてうれしいです:)
レベル4
ところでアントン、私はあなたに同意していました。基本的に、「OP、これがkwargsの目的です。代わりに使用してください」と言っています。
レベル5
おっと、私は誤解しました、それについて申し訳ありません。
レベル6
問題ありません!:D
レベル4
(params={})
レベル4
Pythonを学んでいる人として、それを説明してくれてありがとう。それは私が今何が起こっているのかを理解できる唯一の投稿だからです:D
レベル5
技術的な側面は正しいですが、u / jyonsinやu / dAnjouなどは当然それについて不平を言っています。
Pythonで実行できる多くのトリックと同様に、何が起こっているのかを理解するためにそれらを学びますが、使用しないでください。接吻
レベル2
ここでのポイントは、議論を隠さないことです。**kwargs同様に悪いです。これは、言語のコアに何かが存在するからといって、それが無条件に使用するのに良いことを意味するわけではないことも思い出させてくれます。
関数がその数の引数をとる場合は、多分やりすぎであるか、何らかの方法で相互に依存している可能性があるため、一部の引数をクラスにグループ化することができます。
レベル3
cssやhtmlのようなものに使用するのは良いことです
実行時にキーと値を使用していて、特定のキーを関数にハードコーディングしていない場合は問題ありません
動的なパラメータ名が必要な場合に使用する必要がありますが、決してそうはなりません。
しかし、deffoは時々乱用されます
レベル3
目標がkwargsを他の関数に直接渡すことである場合は問題ありませんが、それ以外は悪いです。
レベル2
TypedDicttypehintもドキュメントに役立ちます。それの大ファン。
https://docs.python.org/3/library/typing.html#typing.TypedDict
3.7を使用していない人にとっては、このバックポートはかなり良いと思います。https://pypi.org/project/typing-extensions/
レベル2
それが50以上でなければ、私はそれを使いません
キーがそのまま印刷されるcssやhtmlのようなものに使用しますが、予期されていないか、関数にハードコードされており、処理されます
レベル3
それなら普通の辞書を使うべきだと思います。(多分あなたはそうします、そして私は私自身の投稿が話していることによって誤解を招きます**kwargs)
しかし、私はあなたがOPのポイントを逃していると思います。あなたの場合、あなたは辞書を辞書として使うだけです。それは正しく、混乱することはありません。OPは、関数自体のパラメーターとして使用される辞書について話しています。
レベル4
プレーン辞書をパラメータとして使用するのはもっと不格好で、pythonicではありません
はい、OPが文句を言うのは正しくないと言ったことは一度もありません。通常のパラメータを使用する必要があるため、OPを使用するのは罪です。
レベル2
ひどい場合には、私は保護ペンタクルを計画し、新しいThingyOptionsクラスを刻みます。危険な主要エネルギーを含み、静的にチェック可能なプロパティ名とタイプメタデータを使用してそれらをチャネル化できます。
レベル1
90年代の私の最初のプロのプログラミングの仕事で、人々はCのポインターで同じことをしました:巨大な構造へのポインターを渡します。それは本質的に、あなたがそうではないふりをしながら、グローバル変数を使ってプログラミングすることです。
レベル2
コードが、定義されたパラメーターの単一のセットを持つ単一の大きなデータセットで実行されるように設計されている場合があります。大きなファットグローバルシングルトンを使用するのがおそらく道のりです(たとえば、大きなparticle_data構造体と大きなrun_params構造体)。大きなユニバーサルデータセットをポインタとして渡すことは、基本的にそのデータストレージパラダイムを使用しようとしますが、不必要に難読化します。
レベル2
eviljelloman11点・4日前
私はFORTRANの一般的なブロックでこのたわごとを覚えています。
レベル3
そしてF77の代替エントリー!ステロイドに行きます!別の機能にジャンプできます!
レベル2
グローバルだけでは問題ではありません。グローバル+可変性が問題です。
レベル2
themostempiracal3点・3日前・3日前に編集
そのようなコードベースに直面している顧客をサポートしたことを覚えています。開発者に一般的なユースケースについて尋ねて、それを文書化できるようにすると、彼らはとても憤慨し、ただ拒否します。
そして、構造体に不正な形式の要素がまったく含まれていましたが、PARAM_INVALIDを返すだけです。それは90年代のhtml400だったと思います。
私と一緒にコードレビューの80%は、私がこのようなことをしている人についてただつまらないことだと誓います。20年前のプログラミングptsdから私を救おうとしているようなものです。
もう1つの返信
レベル1
TypedDictをご覧ください。PyCharmとMyPyに適切に統合されており、辞書に必要なキーとデータの種類を正確に指定できます。これは、事後にdict-paramが散らばっているコードベースに適切な型チェックを追加するための良い方法である可能性があります。
レベル2
これこれこれこれこれ。まだ3.7を使用していない人のためのバックポートです。
https://pypi.org/project/typing-extensions/
レベル1
私はそれだと思う方法であなたがするそれを作るよりも、黒と白。
あなたの例では、確かに、私は心から同意します。しかし、彼らは必ずしも悪ではありません。
たとえば、これらのパラメータは別の関数に渡される場合があります。
def fancy_plot(data,plot1_params=None,plot2_params=None,**kwargs):
if not plot1_params:
plot1_params = {}
if not plot2_params:
plot2_params = {}
call_something_else(**kwargs)
…
この場合、color(a)などのエントリが繰り返され、(b)すべての可能なオプションを列挙することはできません。
ただし、dictをオプションの引数として定義しないように注意してください。
レベル1
これは、他の言語で育ち、Pythonの慣習が好きではない人々の典型的なパターンです。これは、デザイン内の将来のAPI変更との互換性のために記述子に依存する代わりに、X属性のgetX / setXメソッドを作成する人々に似ています。Javaでは、これには将来のオーバーロードを支援するという利点もありますが、Pythonでは、とにかくそれを行う方法ではありません。
とにかく、CやJavaを考えながらPythonを使っている人にはいつもこれが見られます…
レベル2
記述子には問題がある可能性があります。
遅延副作用のある関数があるか、遅延ロードされたHTTPリクエストなどの低速操作を実行して、HALリソースの詳細をフェッチするとします。
これをゲッターとして実装することは、プロパティを使用するよりもはるかにきちんとしたソリューションです。これは、事前に計算された可能性のある応答を使用するのではなく、これが「何かをしている」ことをユーザーに明示的に認識させるためです。構文が同じであるため、プロパティへのアクセスとフィールドへのアクセスを一目で簡単に区別できないことがよくあります。
補足として、依存性注入フレームワークなどのイントロスペクションを使用するものは、注意しないとプロパティを窒息させます。オブジェクトをイントロスペクトするだけでは、プロパティを繰り返し観察して評価するという不幸な副作用があります。オブジェクトの名前空間。
私のポイントは、ゲッターはPythonに存在するということだと思います。それらを頻繁に使用する必要がある場合は、主にユーザーが通常はコードをブラックボックスとして扱い、その後は処理しないため、いくつかのプロパティやいくつかのゲッタースタイルのメソッドを使用するのではなく、一貫して使用する方がよい場合があります。あるものをプロパティとして、別のものをゲッターとして期待するかどうかを知るには、実装の詳細を完全に知る必要があります。
記録のために、私はあなたに同意しません、そして私はプロパティがよりきれいで明確であることに同意します、しかしそれでもそれらをどこで使うかについてそれが常に白黒であるとは限らないことを知っておく価値があります:-)
レベル3
オブジェクトを単に内省するだけでは、プロパティを熱心に観察して評価するという不幸な副作用があります。
私は実際にStackOverflowの最近の回答でこれを調べました。
TL; DR:常にそうであるとは限りません。クライアントコードが副作用を引き起こさないことを気にかけている場合、それはそうすることができ、注意を払う責任があります。
ゲッターの議論に戻ると、副作用を引き起こさないようにプロパティを使用することに警戒している場合は、「getX」をパラダイムとして使用するのではなく、より明示的なもの(計算、フェッチなど)を使用する必要があります。 、混乱を避けるため。しかし、ちょっと、物事に名前を付けることは難しいCSの問題です、そうではありません(他はキャッシュの無効化、および1つずつのエラーです)ので、それはそれらの「文字列の一部の長さ」引数の1つです。
レベル4
同意した
レベル3
うん-私はあなたの正しい観察に直交するJavaの「常にゲッターを使用する」をリフしていました。常にゲッターメソッドを持っているということは、コストについてのシグナルもないことを意味します。私はまた、コストを示すために明示的な名前を使用することについての他のポスターに同意します。
レベル4
私はそれが好み次第だと思います、そしてシンタティックシュガーは本当に。
Kotlinには、Javaクラスがアクセサーやミューテーターに対応するフィールドを持っていると検出した場合、それをプロパティであるかのように扱うという優れた機能がありますが、getX()setX()isXを引き続き使用できます。 ()構文も。記述子はget / setメソッドへの単なる委任であるため、カプセル化を壊すことなく、独自のコードスタイルと設定と相互運用できるので便利です。
レベル1
NicoDeRocca24ポイント・4日前
私が取り組んでいるPythonコードベースのようなひどい使用を見たことがないと言わざるを得ませんが、これはJavaScriptで行われていることに驚くほど近いように見えます。ここでは、コンストラクター/ファクトリのこのイディオムがblah({option:value 、…})
レベル2
JSには最近まで** kwargsに似たものがなかったので、少なくともいくつかの言い訳があります。OPの例では、この種のコンボがない理由はわかりません。
required_param1, required_param2, *args, **kwargs
レベル2
私はそれがまたあるのを見ることができました:
リンターを真剣に受け止めているコーダー(5つ以上の引数がある場合はpylintが文句を言うので、これはそれを回避する方法です)、または
怠惰すぎてすべての引数のdocstringを書くことができません(ただし、これが必要な場所で作業しています。
もう1つの返信
レベル2
私はJavascriptの経験がほとんどありませんが、Seleniumについて読んでいると、Pythonバインディングは、Pythonイディオムに変換せずにJavascriptバインディングをテキストで再実装したものだと感じています(一部の命名規則を除く)。
多分それがこのイディオムの源です。
レベル2
うん、これ。これは明らかに、この慣行が広まっているJSからのパラダイムリークです。最近は誰もがJS開発者を兼ねているように見えるので、彼らの主な役割が何であるかに関係なく、あなたはこのようなものを手に入れます。
レベル2
私はこのようなことをするいくつかのパッケージを知っています。お気に入り
object.load("file")
「ファイル」の値をオブジェクトに格納し、次のようなことを行う
object.apply()
オブジェクトの内部ストレージから値を取得して使用します。そして、それは3つのバリエーションのようなものであり、その適用に応じて、3つの異なる実際の処理関数の1つを呼び出します。
したがって、applyは次のようなものになります
def apply(*args):
if args[0]=="1":
processing_1(*args)
if args[0]=="2":
processing_2(*args)
それは地獄です。
レベル3
これは、すべての単一の処理関数でファイルインターフェイスの書き換えを回避するためのDRYの方法ではありませんか?はい、適用するコードを見ると、関数シグネチャは非常にあいまいですが、ファイル自体の制限について心配するのをやめることができるラッパーであることが意図されています。上記のコードを使用すると、データベースまたはファイル表現の切り替えはクライアントから見えなくなります。
レベル4
私は上手く理解できていない気がします。その過程でコードが読めなくなる方法は考えられません。
抽象化が実際にそのように機能するとは思わない。おそらく、* argsでどちらの方法の癖も隠すことによるメリットはないだろう。
あなたが指摘できる例はありますか?
レベル5
its4thecatlol2点・3日前・3日前に編集
さまざまなソースからのデータの処理を担当するシングルトンオブジェクトにまだサニタイズされていないCSVからデータをロードしていると想像してください。Argsは、nullフィールドを処理するためのフラグを保持します。DBから取得したデータとの互換性のために参照整合性を適用するモードが必要であり、無効なセルを持つすべての行を無視するモードがあり、最も一般的に使用されるデフォルトパラメータでnullセルを埋めるモードがある場合があります。 。もちろん、ラッパーを使用せずに、これら3つのフラグすべてを独自の個別のメソッドにすることができます。ただし、これらのフラグとオプションを受け取り、適切な関数を呼び出すsanitize()ラッパーは、私の好みの設計です。Sanitize()は、Sanitizerクラスまたはモジュール全体の静的メソッドであり、完全に抽象化され、何がどのように行われているかを無視できます。
編集:私はあなたの主張を理解していると信じています。はい、より高度な抽象化でコードの実装を公開すると、何がより良く起こっているのかが明らかになりますが、非常にきれいに分離できるロジックの緊密な結合も引き起こします。ここではユースケースが重要です。apply()が機能するフラグが3つある場合は、投稿したコードを使用します。30ある場合は、それらを取得する方法が多すぎる作業を行っている可能性があります。このパターンを見て混乱することが多い場合は、コードベースのコントラクトが明確に定義されていないと思います。
レベル1
MrGaladash13点・4日前・3日前に編集
私は確かに同意します。私はこれを機械/産業エンジニアのコードでよく見ました。私の見解では、コードを「クリーン」にするために行われ、MATLABがその関数に使用するのが好きなオプションパラメーターです。1つの変数のみを使用して渡すことができる名前付きパラメーターです。また、通常、明確な関数定義ではなく、汎用の「run()」関数で実行されます。
それにもかかわらず、理解/デコードするのは非常に困難ですが、うまくいけば、この視点が何らかの視点を与えるでしょう。
編集:文法
レベル2
FooOptionsクラスを記述して、fooのオプションを明確にするのは簡単です。辞書や** kwargsを受け入れるよりも手間がかかります。
レベル3
ELI5できますか?
レベル4
基本的に、辞書の代わりにクラスを使用して、関数がそのクラスのインスタンスを予期するようにします。このクラスは、関数が期待するものの明確な構造です。
辞書はあいまいで簡単に変更できますが、クラスとしては毎回同じプロパティを期待して適用できます。
レベル1
何でもそうですが、それは合法的な用法を持っています。ただし、引数がわかっている場合は、引数をデータクラスまたは名前付きタプルにする方が適切な場合がよくあります。
よく引用される「パラメータを追加するのはとても簡単です」という議論を完全に拒否します。パラメータを追加する場合は、データクラスを同時に更新できるように、それらのパラメータを処理するコードも追加する必要があります。
レベル1
これは「JavaScriptしか知らない。それは彼らがブートキャンプで教えたものだからだ。ブートキャンプが心配しないように言ったので、言語ガイドを見ることすらしなかった」という症状だと思う。
レベル1
私が働いている会社は、ほぼ完全にタプルの辞書を使用してデータを渡しているので、私は死にたくなります。
レベル1
これは、JavaScriptで一般的に受け入れられているパターンです。あなたは多くの元ウェブ開発者と仕事をしていると思います
さらに2件の返信
レベル1
tunisia350716点・4日前
同意しません。dictであってはならないものにdictを使用することが、この特定の問題の根本です。ディクトは、存在する特定のキーに依存するべきではありません(リストが特定の意味を持つ特定のインデックスに依存するべきではないのと同じように):特定のタイプから特定のタイプに同種の方法でマップする必要があります。意味のあるキーを使用した構造化マッピングが必要な場合は、多数のdefault-Noneフィールドを含むデータクラスを使用するか、APIを再考してください。
残念ながら、優れた設計はさておき、このパターンは、許可されているという理由だけで既存のPythonで非常に一般的であり、「大まかな」コードに便利です。型注釈は、インターフェースについてより深く考えるのに役立つため、これに役立ちます。
ディクトは、それ自体が長い署名を持つ複数の呼び出し可能オブジェクトをラップする関数がある場合にのみ、このパターンで実際に使用する必要があります。そして、これでさえ少し匂いがすることがあります(ビルダー、またはコンポジションを使用できますか?)。例えば:
def wrapper_fn(arg1_1, arg1_2, arg2_1, fn1_kwargs=None, fn2_kwargs=None):
result1 = fn1(arg1_1, arg1_2, **(fn1_kwargs or {}))
result2 = fn2(arg2_1, **(fn2_kwargs or {}))
…
return something_else(result1, result2)
レベル2
ディクトは、存在する特定のキーに依存するべきではありません
どうtyping.TypedDictですか?それはその機能の全体的な目的であり、したがってPythonFoundationのユースケースを念頭に置いているのではないでしょうか。
レベル3
はい。ただし、IMOは、あまり良くない使用パターンをさかのぼって検証するための言語機能を導入する場合です。
レベル2
こんにちは、tunisia3507。ちょっと頭を上げてください!
コードブロック/モノスペーステキストブロックにトリプルバックティック( “ `)を使用しようとしたようです。
これはredditで普遍的にサポートされていません。一部のユーザーにとって、コメントは意図したとおりに表示されません。
代わりに4つのスペースですべての行をインデントすることでこれを回避できます。
新しいRedditの「コードブロック」フォーマット機能のように、少し優れた互換性を提供する他の方法もあります。
良い一日を、tunisia3507。
このコメントに「backtickopt6」と返信すると、オプトアウトできます。「backtickbbotdm5」で応答する代わりに、PMにアラートを送信するように構成します。「dmmode_end」を送信してPMModeを終了します。
さらに4件の返信
レベル2
データクラス
一部の人々は口述を使用することに反対し、クラスは物を保管する方法であるという意見を持っています。
彼らは異教徒です。
真の信者は正しい方法を知っています。それは、クラスを使用することに反対し、口述が物を保存する方法であるという意見を保持することです。
レベル3
静的型付けトレインに乗るか、Python 3.4のままにしてください!汽車ポッポ!
レベル4
(life_of_brian_stoning.mp4)
レベル2
ええ。Djangoはいつも彼のことをしています。
レベル2
意味のあるキーを使用した構造化マッピングが必要な場合は、デフォルトのNoneフィールドが多数あるデータクラスを使用するか、APIを再考してください。
また、名前付きタプルも適切なオプションです。
レベル3
確かに、それらを開梱することもできます*args。彼らがデフォルト値も許可したことを私は覚えていませんでした。
レベル1
動的型付け言語へようこそ!これですべて問題ありませんが、機能が文書化されていない場合は、袖をまくり上げてください。
レベル1
これは小さな関数には問題ありませんが、大量の多様なデータのデータ分析を実行する場合、辞書はそれをカプセル化する簡単な方法です。
レベル2
ただし、データと引数/パラメータの受け渡しには意味上の違いがあります…
レベル3
それは実際には意味がありません。引数とパラメータはデータです。すべての変数はデータを保持し、そのデータを他のコードと共有するための引数またはパラメーターとして使用できます。
class / dictを使用して、引数として渡すデータを保持することは、別の形式のデータを引数として渡すことと意味的には異なりません。これらはすべて同じものです。
レベル4
コードを読み取るのはコンパイラだけではありません。人間へのインターフェースは非常に複雑で(そして興味深いimo)、それを簡単にするための言語機能が存在します。dictと仮パラメーターのリストに同じ情報を含めることができますが、dictには自己文書化がありません。
さらに6件の返信
レベル1
>引数として定義が不適切な辞書を使用して関数を定義することは絶対にありません。
この文で「辞書」を置き換えることができる単語はありますか?それは問題ではありませんか?
レベル2
他のほとんどのタイプは辞書よりも強く定義されていますが、十分に公平です。ここで、私は辞書よりもさらに悪いものを思いついた:
class Params:
"""doesn't define the parameters"""
pass
params = Params()
params.why_wasnt_this_an_argument = 'bar' # add new attributes
foo(params)
でも、わざと残酷にならないと思いつくのは難しいと思います。
レベル3
こんにちは、ジョンシン。ちょっと頭を上げてください!
コードブロック/モノスペーステキストブロックにトリプルバックティック( “ `)を使用しようとしたようです。
これはredditで普遍的にサポートされていません。一部のユーザーにとって、コメントは意図したとおりに表示されません。
代わりに4つのスペースですべての行をインデントすることでこれを回避できます。
新しいRedditの「コードブロック」フォーマット機能のように、少し優れた互換性を提供する他の方法もあります。
良い一日を、ジョンシン。
このコメントに「backtickopt6」と返信すると、オプトアウトできます。「backtickbbotdm5」で応答する代わりに、PMにアラートを送信するように構成します。「dmmode_end」を送信してPMModeを終了します。
レベル1
mypyの `TypedDict`を使用して、必要なコントラクトを追加できます。
https://mypy.readthedocs.io/en/latest/more_types.html#typeddict
おそらく、リファクタリングを行う前の最初のステップは、入力することです。私はPythonのタイピングに錆びているので、コンパイルする例を示すことができるかどうかはわかりませんが、これが最善の方法です。
FooParams = TypedDict(
'FooParams', {'language': str, 'why_wasnt_this_an_argument': str}, total=False)
def foo(params: FooParams):
why_wasnt_this_an_argument = params['why_wasnt_this_an_argument']
# do something
print('kill me')
それを超えて、Pythonでのこれらの状況のほとんどは、たとえばキーワード引数の領域です。
def foo(*, param_1, param_2, param_3=default_value):
…
args = {"param_1": 1, "param_2": 2}
foo(**args)
しかし、少なくとも問題は、コードのセマンティクス、ドキュメント、変数名ではないと思います。フラグを調整するための「オプション」辞書は、前代未聞ではありません。必要なのは、ドキュメントコメントまたは型宣言のいずれかだけです。
多分使用する他のものはデータクラスでしょう。dictを渡す代わりに、必要なデータを保持するクラスを作成します。これは、データ表現としての辞書の操作がより嫌われる非動的言語でのソリューションの必要性に近いものです。
import dataclasses
@dataclasses.dataclass(frozen=True)
class StuffAggregate:
field_1: str
field_2: Union[Literal["red"], Literal["blue"]]
一般に、広く普及している「アンチパターン」は、特異性の結果であることがめったになく、パターンが何のために作られたのか、または言語の機能を知らずにパターンを使用した結果です。教育やコミュニケーションの問題などの問題を、自分自身とチームの他のメンバーの両方のために扱います。なぜ彼らがこれを行うのか理解できませんが、同じ目標を達成するための選択肢の全幅を理解していない可能性があります。
レベル1
これは、初期の柔軟性のためにまだ良い考えです。クラスを使用する方が簡単なので、少なくとも固定された値の定義セットがあります。最初は、同様のパラメータを受け入れるすべての関数の代わりにクラスを変更できます。最適なアーキテクチャを見つけたら、後で改良することができます。私はこれを常にステートマシンパターンから始めています。
レベル1
十数個の位置引数を取ることは、これ以上良いことではありません。
最近たくさんのGoプログラミングを行ったので、私が伝えたい引数がたくさんあるというまれな状況のために、Pythonの世界に戻ると思うパターンがあります。
@dataclass
class FooParams:
thing: int
stuff: str
…
def foo(params: FooParams) -> whatever:
…
あなたはそれを次のように靴べらにすることができるかもしれません:
def foo(raw_params: Dict[str, Any]) -> whatever:
params = FooParams(**raw_params)
…
そうは言っても、私は可能な限りほんの一握りの議論に固執するつもりです。
レベル1
では、これをコーディングする正しい方法は何ですか?
レベル2
実際のパラメータを渡します。
ええと;
def foo(why_wasnt_this_an_argument):
レベル1
これはただの悪いコードです。与えられた理由の1つがパラメーターの量である場合は、名前付きタプルを使用するようにコードをリファクタリングします。これは、広範な引数のセットを宣言し、それらを一度に渡すための優れた方法です。
レベル2
名前付きタプルの方が優れているのはなぜですか?
レベル3
私はOPではありませんが、先に進んで、それは良くないと言います… dictとしてパラメータを「必要」または送信したい人は、名前付きタプルが優れているかどうかを考えるのをやめません。技術的には無意味です。そういえば、そうですか?そして、それが口述である理由をどうやって知るのでしょうか。
とにかく、名前付きタプルはデフォルトで不変であり、本質的に構造を追加するため、これには名前付きタプルの方が適していると思います。これも、dictを使用している人はおそらく望まないでしょう。
もう1つの返信
レベル1
これを行う価値があるのは、Jsonペイロードを取り込んで、使用するパラメーターを選択できるようにする場合のみです。
レベル1
反対票を持参してください!
ジャンクドロワーデータのグラブバッグに辞書を詰め込むことについては誰もが正しいですが…予測可能に作成された辞書の明確に定義された不均一な組み合わせは許容されます。
本当の理由は、Pythonでのデバッグは、他の「より欠陥のある」言語では一流ではないということです。Javaのように…非常に多くのデバッグ情報とそれを見る方法は同等のデータを決定します。(私はJavaでの作業を楽しんでいませんが、時々それが私にとってボールが跳ね返る方法です。)
また、私は常にリストを引数として渡します。多くの場合、個々のデータチャンクをリファクタリングし、dictが渡されたときにリストを残します。それがいくつかの変数とリストになった後…これはより良い方法です。
レベル2
反対は私にとって真実です。Javaのデバッグは通常、無関係なデータで溢れていますが、まともなPythonデバッガーはクリーンです。とにかく、dictがこれと何の関係があるのかわかりません。まともなデバッガフロントエンドは、すべてのパラメータとローカル値を別々に表示するのに問題はありません。
レベル3
それはすべて無関係です…あなたが必要とするものを除いて。Javaはあなたにあまりにも多くを与えます…非常に真実です。しかし、あふれている混乱のどこかで最終的に答えた質問が100%あります。
Pythonが正しく問題がある場合、Pythonのデバッグは少し難しくなりますが、デバッガーが示す範囲外で爆発します…
レベル4
非同期Pythonのデバッグは、特定のレベルの地獄であり、おそらく、コンパイル時が保証された型付き言語に対して人々が作成できる最良のユースケースです。
レベル1
それは愚かなコードです。少なくとも** kwargsを使用してください。
レベル1
反対票で私にシャワーを浴びせてください、しかしそれはそのような弱いタイプの言語の結果です。これらすべての関数がパラメーターとして何をとるかをどのように知る必要がありますか?文字通り何でもかまいません。
レベル2
Pythonは強い型の言語であり、弱い型の言語ではありません。ただし、動的に型指定されます。パラメータの型を知りたい場合は、関数宣言で型ヒントを使用できます。
レベル3
丁度。これらの問題は、型のヒントと適切に表現されたdocstringで解決できないものではありません。
レベル4
あなたが正しいです!
さらに11件の返信
レベル2
Pythonは一般に、強く型付けされた言語と考えられています。たとえば、JavaScriptとは異なり、intとstrを比較することはできません。また、JavaScriptとは異なり、===演算子は必要ありません。
ただし、これはPythonが動的に型指定された言語である結果です。これが、タイプヒントが導入された理由です。しかし、私の意見では、Pythonは静的に型付けされないことが布告されているため、型のヒントはあまりにも多くの労力を費やし、報酬が少なすぎます。しかし、私は逸脱します。
レベル3
うん、すみません、動的に型付けするつもりでした。
レベル3
ただし、Python3は、intvsの限られたケースでは、わずかに弱く型付けされていfloatます。
レベル4
同意しました。しかし、それ自体はキャスティングとは関係がないと思います。まだ調べていませんが、たとえば2項演算子の実装など、演算子の両側で任意のプリミティブ数値タイプを処理できるようになっていると思います。
もう1つの返信
レベル1
これは非常に一般的ですが、通常、人々はそれを「kwargs」または「extra」と呼びます。すべての中間コードに影響を与えることなく引数を追加できるのは怠惰な習慣であり、すぐに混乱を引き起こします。
テストを作成するときは、リファクタリングして実際の引数に変換できます。
レベル1
みなさん、このコードはすばらしいPythonです。あなたの独断的な「パイソン」の理想を取りに行き、それを突き動かしてください。
OP、パターンが気に入らない場合は、リファクタリングしてPRを送信してください。それが単なるコードの臭いなら、それはうまくいくでしょう。実際にそのような理由があった場合は、リファクタリング中にそれを発見し、より重要な問題に注意を払うべきだったことに気付くはずです。
さらに7件の返信
レベル1
namedtuple ftw
レベル1
それが私がFastAPIで気に入っていることです。Typescriptを愛する人として、Pydanticによる型宣言はPythonの天の恵みです。
レベル2
pydanticは私の赤ちゃんを持つことができます
レベル1
私がこのパターンを使用したのは、ほとんどの場合、委任先のすべての署名を意図的に知らない、ある種のミドルウェアまたはコンビネータです。
レベル1
**kwargsハッキングすることで(を使用せずに)アンチパターンにさらに進むことができglobals()ます(関数スコープでlocals()は機能すると思いますが、読み取り専用です):
def f(adict):
for _k, _v in adict.items():
globals()[_k] = _v
インスタンス変数を使用する方が簡単です(アンチパターンは少なくなります)。
class Foo:
def __init__(self, **adict):
# you can use either unpacking or not here, it doesn't matter
# unpacking allows you to direct ref the argument name but
# doesn't make too much sense in __init__ if trying to
# dynamically initialize object state
for _k, _v in adict.items():
setattr(self, _k, _v)
レベル1
!
レベル1
私はwut ** kwargsが理解しているが、なぜそれの鍵を取得するためだけにdictを渡すのか気にしない
レベル1
私はこれを行いますが、このように:
def foo(**kwargs):
first = kwargs.get(‘first’)
これは、任意の数の列を含む可能性のあるテーブルを取り込んでいるが、考えられるすべての列のコードを壊したくないためです。
レベル2
なぜcolumnsパラメータを持っていないのですか?
レベル3
結果に表示される可能性のある現在可能な168列をハードコーディングしたくないためです。
これは自動化されたプロセスの一部です。コードのこのビットはリターンを渡され、リターンは可変です。列が0個、5個、168個の場合があります。
レベル1
私の教授は、コンパイルすらしないコードよりも、くだらない変数と省略されたコメントの方があなたを大幅に削減します。変数名があなたのようなものでなければ、LeftRearMotorSpeedControllerすぐにポップされます。
レベル1
他の多くの人が述べているように、**kwargsここにあなたの友達がいます。引数が多すぎて関数のシグネチャが読みにくい場合は、パラメータをdictに入れることをお勧めします。
レベル1
また、これは、このサブでもっと見るべき種類の投稿の素晴らしい例です。友よ、あなたの金を取りなさい。
レベル1
強く型付けされた言語でコーディングする必要があります
レベル1
私が潜水艦を見るまで、これは政治的なポストだと完全に思っていました
レベル1
そのため、データクラスを作成し、奇妙な型システムを使用します
レベル1
APIを呼び出すための監視ツール用に構築されたライブラリを使用して、現在これに対処しています。約40の異なるライブラリに隠されたパラメータ。
レベル1
より良いコメントをすべて書いてください!!!
レベル1
これはたくさんあります。リモートで似たようなものを使用することになったのは、JSONオブジェクトをカスタムプロセッサに渡さなければならないときだけです。それを回避する方法はありません。解析されたdictを関数の引数として受け入れるだけです。
レベル1
def foo(*args, **kwargs):
"""
function that takes all inputs you provide and makes all the outputs you need
*args: see documentation for foo
**kwargs: see documentation for foo
"""
return x/0
レベル1
かつてtkinterアプリのコードベースを乗っ取ったとき、私はこれをとても嫌いでした…
レベル1
めったに使用されない潜在的なオプションが大量にあるものに役立ちます。
HTMLタグのレンダリングについて考えてみてください。考えられるすべての属性について考えてから、data-スタイル属性もあることを思い出してください。
これらすべてを関数の引数のセットに入れようとすると、お尻が痛くなるだけでなく、コード管理の観点からも無責任になります。
レベル1
このコードは、Javaまたは**kwargs簡単ではない他の言語から移植されていますか?
レベル1
さて、ケーキの上の桜は、デフォルトとしてdictを設定することもできます。
# REALLY BAD ! NEVER DO THIS !
def foo(params={'W_T_F': 'O_M_G'}):
nothing_makes_sense_anymore = params['where_i_got_this_from']
# do something
print('kill me')
これを行う人は誰でも恐ろしい驚きに目覚め、途中で何時間も失う可能性があります。
ヒント:以前の呼び出しのパラメーター値が使用されている可能性があり、わかりません。
レベル1
これについて私が見ているユースケースは、通常、外部サービスからのキー値パラメーター(Webクエリ文字列パラメーター)または一般化/パイプライン処理のための「コンテキストのバッグ」の構成可能な解析です。
ただし、これらの「コンテキストのバッグ」内の特定のキーに依存するようにクラスを構成できるようになるまで、これを抽象化するのは非常に簡単です。これは、読みやすさとテストの両方に役立ちます。
特に、djangoテンプレートは「コンテキストのバッグ」に大きく依存していますが、それを抽象化します。異種シーケンスのプリミティブ型は悪いインターフェースです。そのため、「タプルは異種であり、リストは同種です」という古いものは私には決してありません。ベストプラクティスの異種タイプはクラスです。
レベル1
値(Noneを含む)を渡すことと何も渡さないこととが異なる場合にのみ、キーワード引数に対してこれを行ったと思います。一部のライブラリは、デフォルトとして使用するクラスを作成して、コードで違いがわかるようにしているのを見てきましたが、それは私には醜い感じでした。この問題のクラスを作成すると、ブール値がPythonにまだ組み込まれていないことを思い出します。
レベル2
ブール値がPythonにまだ組み込まれていないとき。
いつでしたか?
レベル3
Python2.3でブール値が追加されました
おもしろい事実:下位互換性のために、TrueとFalseはPython 3まで予約されたキーワードではなかったので、Python 2.xでは、他の人を混乱させるためにそれらを再定義できました。
レベル4
TrueとFalseがなかったことを覚えていないと言うつもりでしたが、2.2では1と0として追加されました。2.2より前に使用したことはありません。
レベル1
Configurationオプションフィールドを使用してデータクラスの作成を開始しました。
関数の名前空間を曇らせることなく、同じ柔軟性を提供します。
レベル1
.get(” KEY”)は私の命を救いました。
レベル1
関数の例に「foo」という名前を使用しているのは今のミームですか?
レベル2
はい、「今」とは「過去60年間」を意味する場合はそうです。
レベル1
私はあなたが言っていることを理解し、それが私が型ヒントを使用する理由の1つです。おそらくそれは私がC ++でプログラミングすることがほとんどで、argsの型と戻り値の型がちょっと気になるからです。
レベル1
この。神よ、これは何度も。つまり、それをファック、なぜ変数さえ持っているのですか?プログラム全体をあいまいなデータパイプラインの「ブラックボックス」にして、反対側から出てくるものがあなたが望むものであることを願っています。/ s
レベル2
最近、雇用保障には余分な努力が必要です。クリンゴン語でドキュメントを書くだけではもはや十分ではありません。
レベル1
これは静的に型付けされた言語から来た人々の典型的な例です笑
レベル2
いいえ、その逆です。それはダイナミズムの実行です。
レベル1
次のレベルは、通過するプリミティブがたわごとであることを認識することです。値オブジェクト/ DTO:s /エンティティを使用します。
レベル1
これは、非決定論的なコンテキストをチェーンで渡す必要がある場合に、それを処理するための適切な方法です。おそらく実際の例ではそうではありません。
レベル1
それはPythonの初期の頃から、レコードや構造体のようなものができる前のことだと感じました。より正式なデータ構造を持つ静的に型付けされた言語から来るのは間違っていると感じた辞書を使って、あらゆる種類のことをしている人々を見ました。
レベル1
はい先輩
レベル1
Pythonではこれを見たことがありません。
しかし、90年代のC ++ COMコンポーネントシステムでは、「value GetAttribute(stringkey);」を使用してCOMコンポーネントへの参照を渡します。関数に必要なパスワードを取得する方法は、決して一般的ではありませんでした。
実際、この経過日数のモデルは、2015年までに開発されていたフライトシステムソフトウェアによってまだ使用されていました。
しかし、ラッパーオブジェクトのない辞書/マップは少し怠惰です。