python中是否有内置的标识函数?
我想指出一个什么都不做的函数:python中是否有内置的标识函数?,python,python-3.x,python-2.7,Python,Python 3.x,Python 2.7,我想指出一个什么都不做的函数: def identity(*args) return args 我的用例是这样的 try: gettext.find(...) ... _ = gettext.gettext else: _ = identity 当然,我可以使用上面定义的标识,但是内置的肯定会运行得更快(并避免我自己引入的bug) 显然,map和filter对标识使用None,但这是特定于它们的实现的 >>> _=None >&
def identity(*args)
return args
我的用例是这样的
try:
gettext.find(...)
...
_ = gettext.gettext
else:
_ = identity
当然,我可以使用上面定义的标识
,但是内置的肯定会运行得更快(并避免我自己引入的bug)
显然,map
和filter
对标识使用None
,但这是特定于它们的实现的
>>> _=None
>>> _("hello")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
>>>\uuu=无
>>>("你好")
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:“非类型”对象不可调用
你的会很好用的。当参数数量固定时,可以使用如下匿名函数:
lambda x: x
做了更多的研究,没有,一个功能被要求在和来自: 最好让人们写下自己的琐碎经历 想想签名和时间成本 因此,更好的方法实际上是(lambda避免命名函数):
- 优点:采用任意数量的参数
- 缺点:结果是参数的装箱版本
- 优点:不会更改参数的类型
- 缺点:仅接受1个位置参数 不,没有 请注意,您的
标识
:
In [6]: id = lambda *args: args
In [7]: id(3)
Out[7]: (3,)
lambda arg:arg
注意:本例将隐藏内置的
id
函数(您可能永远不会使用该函数) 这根线很旧了。但还是想把这个贴出来
可以为参数和对象构建标识方法。在下面的示例中,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}
中定义的标识函数接受单个参数,并返回不变的参数:
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
具有相同调用约定和返回的函数,该函数返回的参数不变,并清楚地命名以描述它的功能和用途。如果性能是这里的关键考虑因素,我会非常震惊。单参数函数的存根
(OP的示例用例)接受一个参数,message
。如果需要存根,则没有理由返回[message]
,而不是message
(def identity(*args):返回args
)。因此两者
_ = lambda message: message
def _(message):
return message
非常合适
…但内置的程序肯定会运行得更快(并避免我自己引入的bug)
在这样一个微不足道的案例中,bug几乎不相关。对于预定义类型的参数,例如str
,我们可以使用str()
本身作为标识函数(因为它甚至保留对象标识,请参见下面的id
注释),并将其性能与lambda解决方案进行比较:
$ 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
微观优化是可能的。例如,以下代码:
test.pyx
然后:
内置对象标识函数
不要将标识函数与内置函数混淆,内置函数返回对象的“标识”(与
==
运算符相比,表示该特定对象的唯一标识符,而不是该对象的值),其内存地址为CPython。Python中没有内置标识函数。仿效的做法是:
identity = lambda x, *args: (x,) + args if args else x
用法示例:
identity(1)
1
identity(1,2)
(1, 2)
由于
identity
除了返回给定的参数外,什么都不做,因此我认为它不会比本机实现慢。如果速度不重要,这应该可以处理所有情况:
def identity(*args, **kwargs):
if not args:
if not kwargs:
return None
elif len(kwargs) == 1:
return next(iter(kwargs.values()))
else:
return (*kwargs.values(),)
elif not kwargs:
if len(args) == 1:
return args[0]
else:
return args
else:
return (*args, *kwargs.values())
用法示例:
print(identity())
None
$identity(1)
1
$ identity(1, 2)
(1, 2)
$ identity(1, b=2)
(1, 2)
$ identity(a=1, b=2)
(1, 2)
$ identity(1, 2, c=3)
(1, 2, 3)
您所说的映射和过滤器对标识使用无是什么意思?@MattFenwick:
map(无,[1,2,3])
检查返回值。您的args变量将是(在本场景中)一个值的序列,因此要么在声明中省略星号,要么在返回之前将其解压。@GregHewgill:遗憾的是,这在Python 3.x中不起作用。@GregHewgill My bad。我在谷歌搜索后从医生那里得到的。但是Python2.x文档总是排在第一位……您也可以使用varargs做到这一点:lambda*args:args
。这确实是一种风格上的选择。我更喜欢第二种,因为它可以接受任意数量的参数。@delnan@rds-the*args
版本有不同的返回类型,所以即使对于单参数情况,它们也不相同。@delnan:你说这是一种风格上的选择,这错误地暗示了这两种形式的语义没有区别。@Marcin:如果我这样暗示的话,那就太不幸了。对于这样简单的函数,我的意思是在def
和lambda
之间进行选择。请注意,这不是一个标识函数。@Marcin感谢您的回复
identity = lambda x, *args: (x,) + args if args else x
identity(1)
1
identity(1,2)
(1, 2)
def identity(*args, **kwargs):
if not args:
if not kwargs:
return None
elif len(kwargs) == 1:
return next(iter(kwargs.values()))
else:
return (*kwargs.values(),)
elif not kwargs:
if len(args) == 1:
return args[0]
else:
return args
else:
return (*args, *kwargs.values())
print(identity())
None
$identity(1)
1
$ identity(1, 2)
(1, 2)
$ identity(1, b=2)
(1, 2)
$ identity(a=1, b=2)
(1, 2)
$ identity(1, 2, c=3)
(1, 2, 3)