tldr; format
呼び出して、さらに高レベルの処理を行うメソッドobj.__format__
によって使用されます。str.format
下位レベルでは、オブジェクト自体をフォーマットする方法をオブジェクトに教えることが理にかなっています。
それは単なる構文糖です
この関数が名前と形式の仕様を共有しているという事実は、str.format
誤解を招く可能性があります。の存在str.format
は簡単に説明できます。複雑な文字列補間を行います (古い%
演算子を置き換えます)。format
仕様の最小のサブセットである文字列として単一のオブジェクトをフォーマットできますstr.format
。では、なぜ必要なのformat
でしょうか?
この関数は、一部のOO言語に見られる構造format
の代替です。この決定は、(Python がJavascriptや Rubyのようなプロパティの代わりに関数を使用する理由について)の論理的根拠と一致しています。obj.format('fmt')
len
len(x)
x.length
言語がobj.format('fmt')
コンストラクト (または など) を採用すると、クラスは (またはobj.length
、おわかりのobj.toString
ように) という名前の属性を持つことができなくなります。そうしないと、言語から標準メソッドが隠されます。この場合、言語設計者は名前の競合を防ぐという負担をプログラマーに課しています。format
length
toString
Python はPoLA__dunder__
を非常に気に入っており、ユーザー定義の属性と言語の組み込みとの間の競合の可能性を最小限に抑えるために、組み込みに (二重下線) 規則を採用しています。もちろんの代わりに呼び出すことができます ( の代わりに呼び出すobj.format('fmt')
ことができるのと同じ方法)。obj.__format__('fmt')
obj.__format__('fmt')
format(obj, 'fmt')
obj.__len__()
len(obj)
あなたの例を使用して:
>>> '{0:x}'.format(13)
'd'
>>> (13).__format__('x')
'd'
>>> format(13, 'x')
'd'
どちらがきれいで入力しやすいですか? Python の設計は非常に実用的であり、よりクリーンであるだけでなく、Python のダックタイプのオブジェクト指向アプローチとうまく連携しており、言語設計者はレガシー コードを壊すことなく、基礎となる実装を自由に変更/拡張できます。
PEP 3101は新しいstr.format
メソッドとformat
ビルトインをformat
関数の理論的根拠についてのコメントなしで導入しましたが、実装は明らかに単なる構文糖衣です:
def format(value, format_spec):
return value.__format__(format_spec)
そして、ここで私は自分のケースを休ませます。
それについてGuidoが言ったこと(またはそれは公式ですか?)
まさにBDFLの引用len
:
まず第一に、私はHCIの理由で選択len(x)
しx.len()
ました (かなり後で来ました)。実際には 2 つの絡み合った理由があり、どちらもHCIです。def __len__()
(a) 一部の演算では、前置記法は後置記法よりも読みやすい — 前置記法 (および中置記法!) 演算には、数学において長い伝統があり、ビジュアルが数学者が問題について考えるのに役立つ記法が好まれます。式を簡単に書き直すことと、生の OO 表記を使用して同じことを行うことの不器用さをx*(a+b)
比較してください。x*a + x*b
len(x)
(b)何かの長さを要求していることを知っているというコードを読んだとき。これは、結果が整数であることと、引数がある種のコンテナであることの 2 つを示しています。逆に、 を読むときはx.len()
、それがx
インターフェースを実装するか、標準のlen()
. マッピングを実装していないクラスにget()
orkeys()
メソッドがある場合や、ファイルではない何かにメソッドがある場合に、時々混乱することがありますwrite()
。
同じことを別の言い方をすれば、「<code>len」は組み込み操作と見なされます。それを失うのはもったいない。/…/
ソース: pyfaq@effbot.org (ここの元の投稿には、Guido が回答していた元の質問も含まれています)。アバーナートは次のことも提案しています。
Design and History FAQに len に関する追加の理由があります。完全ではない、または適切な回答ではありませんが、間違いなく公式です。–アバーナート
これは実用的な問題ですか、それとも単なる構文の問題ですか?
これは、Python、 Ruby 、Javascriptなどの言語では非常に実用的で現実的な問題です。動的に型付けされた言語では、変更可能なオブジェクトは事実上名前空間であり、プライベート メソッドまたは属性の概念は慣例の問題だからです。おそらく、彼のコメントでabarnertよりもうまく言えませんでした。
また、Ruby と JS の名前空間汚染の問題に関しては、これが動的型付け言語に固有の問題であることを指摘しておく価値があります。Haskell や C++ などの多様な静的型付け言語では、型固有の自由関数が可能であるだけでなく、慣用的です。(インターフェイスの原則を参照してください。) しかし、Ruby、JS、Python などの動的型付け言語では、フリー関数は普遍的でなければなりません。動的言語の言語/ライブラリ設計の大部分は、そのような関数の適切なセットを選択することです。
たとえば、私は Ember での名前空間の競合にうんざりしていたので、 Ember.jsを残してAngular.jsを支持しました。Angular は組み込みメソッドの前に (Python のようなアンダースコアの代わりに Angular で) プレフィックスを付けるエレガントな Python のような戦略を使用してこれを処理するため、ユーザー定義のメソッドやプロパティと競合しません。はい、全体は特にきれいではありませんが、Python がこのアプローチを採用したことを嬉しく思います。これは非常に明示的であり、オブジェクトの名前空間の衝突に関するPoLAクラスのバグを回避できるからです。$thing
__thing__