私は何もしない関数を指し示したい:
def identity(*args)
return args
私のユースケースはこのようなものです
try:
gettext.find(...)
...
_ = gettext.gettext
else:
_ = identity
もちろん、上記で定義したidentity
を使用することもできますが、ビルトインは確かに高速に動作します(そして、自分で導入したバグを回避します)。
明らかに、map
とfilter
はIDにNone
を使用しますが、これは実装に固有のものです。
>>> _=None
>>> _("hello")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
さらなる調査を行っても何もありません。機能は issue 1673203 で尋ねられました。そして、 から't be :
人々が自分で取るに足らないパススルーを書いて、署名と時間コストについて考えることができるようにした方が良い。
したがって、それを行うより良い方法は実際には(ラムダは関数の命名を避けます)です:
_ = lambda *args: args
OR
_ = lambda x: x
https://en.wikipedia.org/wiki/Identity_function で定義されているID関数は、1つの引数を取り、変更せずに返します。
_def identity(x):
return x
_
署名def identity(*args)
が必要だと言ったときに求めているのは、not厳密に恒等関数であり、必要なものです複数の引数。それは問題ありませんが、Python関数は複数の結果を返さないため、これらの引数をすべて1つの戻り値に詰め込む方法を見つける必要があります。
Pythonで「複数の値」を返す通常の方法は、値のタプルを返すことです-技術的には1つの戻り値ですが、複数の値であるかのようにほとんどのコンテキストで使用できます。ここでそれを行うことはあなたが得ることを意味します
_>>> def mv_identity(*args):
... return args
...
>>> mv_identity(1,2,3)
(1, 2, 3)
>>> # So far, so good. But what happens now with single arguments?
>>> mv_identity(1)
(1,)
_
そして、thatの問題を修正すると、ここでのさまざまな答えが示すように、他の問題がすぐに発生します。
したがって、要約すると、Pythonで定義されている恒等関数はありません。
正確な場合、
_def dummy_gettext(message):
return message
_
ほぼ間違いなくあなたが望むものです-同じ呼び出し規約を持ち、引数を変更せずに返す_gettext.gettext
_と同じ関数を返します。ここでパフォーマンスが重要な考慮事項である場合、私はかなりショックを受けるでしょう。
あなたのはうまくいきます。パラメーターの数が修正されたら、次のような匿名関数を使用できます。
lambda x: x
いいえ、ありません。
identity
:
その引数をボックス化します-つまり.
In [6]: id = lambda *args: args
In [7]: id(3)
Out[7]: (3,)
そのため、lambda arg: arg
真の恒等関数が必要な場合。
NB:この例は、組み込みのid
関数(おそらく使用することはないでしょう)をシャドウします。
Pythonには組み込みのID関数はありません。 Haskellのid
関数 の模倣は次のようになります。
identity = lambda x, *args: (x,) + args if args else x
使用例:
identity(1)
1
identity(1,2)
(1, 2)
identity
は与えられた引数を返すこと以外は何もしないので、ネイティブ実装よりも遅いとは思いません。ネイティブ関数の呼び出しが保存されるため、さらに高速になる可能性があります。
_gettext.gettext
_ (OPの使用例の例)は、単一の引数message
を受け入れます。スタブが必要な場合、message
(def identity(*args): return args
)の代わりに_[message]
_を返す理由はありません。したがって、両方
__ = lambda message: message
def _(message):
return message
_
完全にフィットします。
...しかし、ビルトインは確かに高速に動作します(そして、私自身によって導入されたバグを避けます)。
このような些細なケースのバグはほとんど関係ありません。事前定義型の引数、たとえばstr
の場合、str()
自体をアイデンティティ関数として使用できます( string interning によりオブジェクトのアイデンティティも保持されるため、id
以下に注意してください)、そのパフォーマンスをラムダソリューションと比較します。
_$ python3 -m timeit -s "f = lambda m: m" "f('foo')"
10000000 loops, best of 3: 0.0852 usec per loop
$ python3 -m timeit "str('foo')"
10000000 loops, best of 3: 0.107 usec per loop
_
マイクロ最適化が可能です。たとえば、次の Cython コード:
test.pyx
_cpdef str f(str message):
return message
_
次に:
_$ pip install runcython3
$ makecython3 test.pyx
$ python3 -m timeit -s "from test import f" "f('foo')"
10000000 loops, best of 3: 0.0317 usec per loop
_
アイデンティティ関数と、オブジェクトの「アイデンティティ」を返す組み込み関数 id
と混同しないでください(_==
_演算子と比較して、そのオブジェクトの値ではなく、その特定のオブジェクトの一意の識別子を意味します)、CPythonのメモリアドレス。