Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中是否有内置的标识函数?_Python_Python 3.x_Python 2.7 - Fatal编程技术网

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个位置参数
  • 不,没有

    请注意,您的
    标识

  • 相当于lambda*args:args
  • 将装箱其参数-即

    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)