Есть встроенная функция идентификации в 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
:
- эквивалентно лямбда * args: args
Буду упаковывать свои арги - т.е.
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}