Есть встроенная функция идентификации в python?

Я хотел бы указать на функцию, которая ничего не делает:

def identity(*args)
    return args

мой пример использования - это что-то вроде этого

try:
    gettext.find(...)
    ...
    _ = gettext.gettext
else:
    _ = identity

Конечно, я мог бы использовать описанный выше identity, но встроенный, безусловно, будет работать быстрее (и избегать ошибок, введенных самим собой).

По-видимому, map и filter используют None для идентификации, но это специфично для их реализаций.

>>> _=None
>>> _("hello")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable

Ответ 1

Выполняя еще несколько исследований, их нет, функция была предложена в issue 1673203 И из Раймонд Хеттингер сказал, что не будет:

Лучше позволить людям писать свои тривиальные проходы и подумайте о стоимости подписи и времени.

Таким образом, лучший способ сделать это на самом деле (лямбда избегает именования функции):

_ = lambda *args: args
  • преимущество: принимает любое количество параметров
  • Недостаток: результатом является вставка версии параметров

ИЛИ

_ = lambda x: x
  • преимущество: не меняет тип параметра
  • Недостаток: принимает ровно 1 позиционный параметр

Ответ 2

Функция идентификации, определенная в https://en.wikipedia.org/wiki/Identity_function, принимает один аргумент и возвращает его без изменений:

def identity(x):
    return x

Что вы просите, когда говорите, что вы хотите, чтобы подпись def identity(*args) не была строго функцией идентификации, так как вы хотите, чтобы она принимала несколько аргументов. Это прекрасно, но тогда вы столкнулись с проблемой, поскольку функции Python не возвращают несколько результатов, поэтому вам нужно найти способ перекоса всех этих аргументов в одно возвращаемое значение.

Обычный способ возврата "нескольких значений" в Python - вернуть кортеж значений - технически это одно возвращаемое значение, но оно может использоваться в большинстве контекстов, как если бы оно было несколькими значениями. Но выполнение этого означает, что вы получаете

>>> 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,)

И исправление этой проблемы быстро дает другие проблемы, как показали различные ответы.

Итак, в общем, нет никакой функции идентификации, определенной в Python, потому что:

  • Формальное определение (единственная функция аргумента) не так полезно и тривиально писать.
  • Расширение определения до нескольких аргументов в целом не определено, и вам гораздо лучше определить свою собственную версию, которая работает так, как вам нужно, для вашей конкретной ситуации.

Для вашего точного случая

def dummy_gettext(message):
    return message

почти наверняка вы хотите - функция, которая имеет одно и то же соглашение о вызове и возвращает как gettext.gettext, который возвращает свой аргумент без изменений и явно назван, чтобы описать, что он делает и где он предназначен для использования. Я был бы очень шокирован, если бы производительность была решающим фактором здесь.

Ответ 3

ваш будет работать нормально. Когда число параметров исправить, вы можете использовать анонимную функцию:

lambda x: x

Ответ 4

Нет, нет.

Обратите внимание, что ваш identity:

  1. эквивалентно лямбда * args: args
  2. Буду упаковывать свои арги - т.е.

    In [6]: id = lambda *args: args
    
    In [7]: id(3)
    Out[7]: (3,)
    

Таким образом, вы можете использовать lambda arg: arg, если вам нужна функция подлинной идентификации.

NB. Этот пример будет скрывать встроенную функцию id (которую вы, вероятно, никогда не будете использовать).

Ответ 5

В Python нет встроенной функции идентификации. Имитация функции Haskell id будет:

identity = lambda x, *args: (x,) + args if args else x

Пример использования:

identity(1)
1
identity(1,2)
(1, 2)

Поскольку identity ничего не делает, кроме как возвращать заданные аргументы, я не думаю, что он медленнее, чем исходная реализация. Это может быть даже быстрее, потому что он сохраняет вызов собственной функции.

Ответ 6

Множество однопараметрической функции

gettext.gettext (пример использования примера OP) принимает один аргумент, message. Если для этого нужна заглушка, нет причин возвращать [message] вместо message (def identity(*args): return args). Таким образом, оба

_ = lambda message: message

def _(message):
    return message

идеально подходит.

... но встроенный, безусловно, будет работать быстрее (и избегать ошибок, внесенных мной самим).

Ошибки в таком тривиальном случае едва ли актуальны. Для аргумента предопределенного типа, скажем, str, мы можем использовать str() себя как функции идентичности (из - за строки интернирование она даже сохраняет идентичность объекта, см 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.

Ответ 7

Поток довольно старый. Но все же хотелось опубликовать это.

Можно создать метод идентификации как для аргументов, так и для объектов. В приведенном ниже примере ObjOut является идентификатором для ObjIn. Все остальные примеры, приведенные выше, не касались dict ** kwargs.

class test(object):
    def __init__(self,*args,**kwargs):
        self.args = args
        self.kwargs = kwargs
    def identity (self):
        return self

objIn=test('arg-1','arg-2','arg-3','arg-n',key1=1,key2=2,key3=3,keyn='n')
objOut=objIn.identity()
print('args=',objOut.args,'kwargs=',objOut.kwargs)

#If you want just the arguments to be printed...
print(test('arg-1','arg-2','arg-3','arg-n',key1=1,key2=2,key3=3,keyn='n').identity().args)
print(test('arg-1','arg-2','arg-3','arg-n',key1=1,key2=2,key3=3,keyn='n').identity().kwargs)

$ py test.py
args= ('arg-1', 'arg-2', 'arg-3', 'arg-n') kwargs= {'key1': 1, 'keyn': 'n', 'key2': 2, 'key3': 3}
('arg-1', 'arg-2', 'arg-3', 'arg-n')
{'key1': 1, 'keyn': 'n', 'key2': 2, 'key3': 3}