programing

파이썬에 아이덴티티 기능이 내장되어 있습니까?

powerit 2023. 6. 12. 21:58
반응형

파이썬에 아이덴티티 기능이 내장되어 있습니까?

나는 아무 것도 하지 않는 함수를 지적하고 싶습니다.

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

좀 더 연구해 보면, 없습니다. 1673203호에서 특집 기사가 질문을 받았고, 레이먼드 헤팅거는 다음과 같은 내용은 없을 것이라고 말했습니다.

사람들이 자신만의 사소한 패스스루를 작성하고 서명 및 시간 비용에 대해 생각하도록 하는 것이 좋습니다.

따라서 더 나은 방법은 실제로 다음과 같습니다(람다는 함수의 이름을 지정하지 않습니다).

_ = lambda *args: args
  • 장점: 임의의 수의 매개 변수 사용
  • 단점: 결과는 파라미터의 박스 버전입니다.

OR

_ = lambda x: x
  • 장점: 매개 변수의 유형은 변경되지 않습니다.
  • 단점: 정확히 1개의 위치 모수를 사용합니다.

https://en.wikipedia.org/wiki/Identity_function, 정의된 ID 함수는 단일 인수를 사용하여 변경되지 않은 값을 반환합니다.

def identity(x):
    return x

이 서명을 때 은 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠdef identity(*args)여러 개의 인수를 사용하려는 경우에는 엄격하게 ID 함수가 아닙니다.괜찮습니다. 하지만 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에는 ID 함수가 정의되어 있지 않습니다.

  1. 공식적인 정의(단일 인수 함수)는 그렇게 유용하지 않고 쓰기에 사소한 것입니다.
  2. 정의를 여러 인수로 확장하는 것은 일반적으로 잘 정의되지 않으며 특정 상황에 맞게 작동하는 버전을 정의하는 것이 훨씬 좋습니다.

당신의 정확한 경우를 위해,

def dummy_gettext(message):
    return message

거의 확실하게 당신이 원하는 것입니다 - 호출 규약과 리턴이 같은 함수.gettext.gettext이는 변경되지 않은 인수를 반환하며, 이 인수가 수행하는 작업과 사용할 위치를 설명하기 위해 명확하게 이름이 지정됩니다.여기서 성과가 중요한 고려 사항이라면 저는 상당히 충격적일 것입니다.

당신 것은 잘 작동할 것입니다.매개 변수 수가 수정되면 다음과 같은 익명 함수를 사용할 수 있습니다.

lambda x: x

파이썬에는 아이덴티티 기능이 내장되어 있지 않습니다.하스켈 함수의 모방은 다음과 같습니다.

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

사용 예:

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

때부터identity주어진 인수를 반환하는 것 외에는 아무 것도 하지 않습니다. 기본 구현보다 느리다고 생각하지 않습니다.

아니요, 없어요.

의 참로당의신에 하세요.identity:

  1. 람다 *args: args와 같습니다.
  2. 상자에 상자를 넣습니다. 즉,

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

그래서, 당신은 사용하고 싶을지도 모릅니다.lambda arg: arg당신이 진정한 정체성 기능을 원한다면요.

NB: 이 예제는 기본 제공되는 기능에 영향을 미칩니다.id기능(아마도 사용하지 않을 것입니다).

속도가 문제가 되지 않는 경우 다음과 같은 모든 경우를 처리해야 합니다.

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)

단일 인수 함수의 스텁

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

미세 최적화가 가능합니다.예를 들어, 다음과 같은 사이톤 코드가 있습니다.

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)입니다.

이 주제에는 많은 좋은 답변과 토론이 있습니다.ID 함수에 단일 인수가 있는 OP의 경우 컴파일 방식으로 람다를 사용하든 함수를 정의하든(이 경우 PEP8을 준수하도록 함수를 정의해야 함) 상관이 없습니다.바이트 코드는 기능적으로 동일합니다.

import dis
function_method = compile("def identity(x):\n    return x\ny=identity(Type('x', (), dict()))", "foo", "exec")
dis.dis(function_method)
  1           0 LOAD_CONST               0 (<code object identity at 0x7f52cc30b030, file "foo", line 1>)
              2 LOAD_CONST               1 ('identity')
              4 MAKE_FUNCTION            0
              6 STORE_NAME               0 (identity)

  3           8 LOAD_NAME                0 (identity)
             10 LOAD_NAME                1 (Type)
             12 LOAD_CONST               2 ('x')
             14 LOAD_CONST               3 (())
             16 LOAD_NAME                2 (dict)
             18 CALL_FUNCTION            0
             20 CALL_FUNCTION            3
             22 CALL_FUNCTION            1
             24 STORE_NAME               3 (y)
             26 LOAD_CONST               4 (None)
             28 RETURN_VALUE

Disassembly of <code object identity at 0x7f52cc30b030, file "foo", line 1>:
  2           0 LOAD_FAST                0 (x)
              2 RETURN_VALUE

그리고 람다

import dis
lambda_method = compile("identity = lambda x: x\ny=identity(Type('x', (), dict()))", "foo", "exec")
dis.dis(lambda_method)
  1           0 LOAD_CONST               0 (<code object <lambda> at 0x7f52c9fbbd20, file "foo", line 1>)
              2 LOAD_CONST               1 ('<lambda>')
              4 MAKE_FUNCTION            0
              6 STORE_NAME               0 (identity)

  2           8 LOAD_NAME                0 (identity)
             10 LOAD_NAME                1 (Type)
             12 LOAD_CONST               2 ('x')
             14 LOAD_CONST               3 (())
             16 LOAD_NAME                2 (dict)
             18 CALL_FUNCTION            0
             20 CALL_FUNCTION            3
             22 CALL_FUNCTION            1
             24 STORE_NAME               3 (y)
             26 LOAD_CONST               4 (None)
             28 RETURN_VALUE

Disassembly of <code object <lambda> at 0x7f52c9fbbd20, file "foo", line 1>:
  1           0 LOAD_FAST                0 (x)
              2 RETURN_VALUE

모든 답변에 추가:

Python stdlib에는 암묵적인 규칙이 있으며, 여기서 HOF는 기본값으로 사용됩니다.key항등식 함수에 대한 매개변수 함수, 해석None이와 같이

예.sorted,heapq.merge,max,min,기타.

그래서, 당신의 HOF 기대를 고려하는 것은 나쁜 생각이 아닙니다.key같은 패턴을 따르는 것.

즉, 다음을 대신합니다.

def my_hof(x, key=lambda _: _):
   ...

(의견은 전적으로 옳습니다)

다음과 같이 쓸 수 있습니다.

def my_hof(x, key=None):
    if key is None: key = lambda _: _
    ...

네가 원한다면.

실이 꽤 오래됐어요.그래도 이걸 올리고 싶었어요.

인수와 객체 모두에 대해 ID 메서드를 작성할 수 있습니다.아래 예제에서 ObjOut은 ObjIn의 ID입니다.위의 다른 모든 예는 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}

언급URL : https://stackoverflow.com/questions/8748036/is-there-a-builtin-identity-function-in-python

반응형