source

클래스에 정의된 기능이 있는지 확인하는 가장 빠른 방법은 무엇입니까?

factcode 2023. 7. 8. 11:13
반응형

클래스에 정의된 기능이 있는지 확인하는 가장 빠른 방법은 무엇입니까?

저는 AI 상태 공간 검색 알고리즘을 작성하고 있으며, 검색 알고리즘을 빠르게 구현하는 데 사용할 수 있는 제네릭 클래스가 있습니다.하위 클래스는 필요한 작업을 정의하고 알고리즘은 나머지 작업을 수행합니다.

여기가 제가 꼼짝 못하게 되는 부분입니다.상위 상태가 반복적으로 재생성되는 것을 방지하기 위해 다음과 같은 기능을 사용하여 모든 상태에 합법적으로 적용할 수 있는 작업을 반환합니다.

def get_operations(self, include_parent=True):
    ops = self._get_operations()
    if not include_parent and self.path.parent_op:
        try:
            parent_inverse = self.invert_op(self.path.parent_op)
            ops.remove(parent_inverse)
        except NotImplementedError:
            pass
    return ops

그리고 invert_op 함수는 기본적으로 느려집니다.

예외를 잡는 것보다 기능이 정의되지 않았는지 확인하는 더 빠른 방법이 있습니까?

dir에서 선물을 확인하는 선에서 뭔가 생각하고 있었는데, 그건 아닌 것 같습니다.hastr은 gettrr에 전화를 걸어 상승 여부를 확인함으로써 구현되는데, 이것은 내가 원하는 것이 아닙니다.

예, 용을 사용합니다.getattr() , 속을가니다옵져성다▁to.callable()메서드인지 확인합니다.

invert_op = getattr(self, "invert_op", None)
if callable(invert_op):
    invert_op(self.path.parent_op)

:getattr()일반적으로 특성이 없는 경우 예외를 발생시킵니다., value)을 None이 경우) 대신 해당 항목을 반환합니다.

Python 2와 Python 3 모두에서 작동합니다.

hasattr(connection, 'invert_opt')

hasattr아온다를 합니다.True 연결 에 함수가 있다면,invert_opt확정된여기 당신이 풀을 뜯을 수 있는 서류가 있습니다.

https://docs.python.org/2/library/functions.html#hasattr https://docs.python.org/3/library/functions.html#hasattr

예외를 잡는 것보다 기능이 정의되지 않았는지 확인하는 더 빠른 방법이 있습니까?

왜 그것에 반대하십니까?대부분의 파이썬의 경우, 허락보다는 용서를 구하는 것이 낫습니다. ;-)

hastr은 gettrr에 전화를 걸어 상승 여부를 확인함으로써 구현되는데, 이것은 내가 원하는 것이 아닙니다.

다시 말하지만, 왜 그럴까요?다음은 상당히 파이썬적인 내용입니다.

    try:
        invert_op = self.invert_op
    except AttributeError:
        pass
    else:
        parent_inverse = invert_op(self.path.parent_op)
        ops.remove(parent_inverse)

아니면.

    # if you supply the optional `default` parameter, no exception is thrown
    invert_op = getattr(self, 'invert_op', None)  
    if invert_op is not None:
        parent_inverse = invert_op(self.path.parent_op)
        ops.remove(parent_inverse)

그나참고러는 다음과 같습니다.getattr(obj, attr, default)기본적으로 예외를 포착함으로써 구현됩니다.파이썬랜드에서는 아무 문제가 없습니다!

파이썬의 다른 것들과 마찬가지로, 만약 당신이 충분히 노력한다면, 당신은 배짱을 부릴 수 있고 정말 끔찍한 일을 할 수 있습니다.자, 여기 고약한 부분이 있습니다.

def invert_op(self, op):
    raise NotImplementedError

def is_invert_op_implemented(self):
    # Only works in CPython 2.x of course
    return self.invert_op.__code__.co_code == 't\x00\x00\x82\x01\x00d\x00\x00S'

제발 부탁입니다, 당신이 질문한 것을 계속하고 파이파이 팀에서 파이썬 인터프리터를 해킹하지 않는 한 이것을 절대 사용하지 마십시오.저 위에 있는 것은 피톤체이고, 제가 여기 있는 것은 순수한 악마입니다.

여기서 응답은 문자열이 개체의 속성 이름인지 확인합니다.속성이 메서드인지 확인하려면 추가 단계(콜 가능 사용)가 필요합니다.

즉, 객체 obj에 속성이 있는지 확인하는 가장 빠른 방법은 무엇입니까?그 대답은.

'attrib' in obj.__dict__

이는 딕트가 키를 해시하기 때문에 키의 존재를 확인하는 것이 빠르기 때문입니다.

아래의 타이밍 비교를 참조하십시오.

>>> class SomeClass():
...         pass
...
>>> obj = SomeClass()
>>>
>>> getattr(obj, "invert_op", None)
>>>
>>> %timeit getattr(obj, "invert_op", None)
1000000 loops, best of 3: 723 ns per loop
>>> %timeit hasattr(obj, "invert_op")
The slowest run took 4.60 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 674 ns per loop
>>> %timeit "invert_op" in obj.__dict__
The slowest run took 12.19 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 3: 176 ns per loop

저는 네이선 오스트가드의 대답이 마음에 들어서 찬성표를 던졌습니다.그러나 문제를 해결할 수 있는 또 다른 방법은 함수 호출의 결과를 캐시하는 메모 장식기를 사용하는 것입니다.그래서 여러분은 무언가를 이해할 수 있는 값비싼 기능을 가질 수 있습니다. 하지만 여러분이 그것을 계속해서 호출할 때, 그 기능의 메모화된 버전은 딕트에서 인수를 찾고, 실제 함수가 결과를 계산했을 때의 딕트에서 결과를 찾고, 즉시 결과를 반환합니다.

여기 레이먼드 헤팅거의 "lru_cache"라는 메모 장식가를 위한 레시피가 있습니다.이 버전은 이제 Python 3.2의 functools 모듈에서 표준으로 제공됩니다.

http://code.activestate.com/recipes/498245-lru-and-lfu-cache-decorators/

http://docs.python.org/release/3.2/library/functools.html

클래스를 검토할 수도 있습니다.

import inspect


def get_methods(cls_):
    methods = inspect.getmembers(cls_, inspect.isfunction)
    return dict(methods)

# Example
class A(object):
    pass

class B(object):
    def foo():
        print('B')


# If you only have an object, you can use `cls_ = obj.__class__`
if 'foo' in get_methods(A):
    print('A has foo')

if 'foo' in get_methods(B):
    print('B has foo')

__dict__ 속성에서 속성을 확인하는 것은 매우 빠르지만 __dict__ 해시에 나타나지 않기 때문에 메서드에 이 속성을 사용할 수 없습니다.그러나 성능이 그렇게 중요한 경우에는 클래스에서 해킹 해결 방법을 사용할 수 있습니다.

class Test():
    def __init__():
        # redefine your method as attribute
        self.custom_method = self.custom_method

    def custom_method(self):
        pass

그런 다음 다음 방법을 확인합니다.

t = Test()
'custom_method' in t.__dict__

과의 시간 비교getattr:

>>%timeit 'custom_method' in t.__dict__
55.9 ns ± 0.626 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

>>%timeit getattr(t, 'custom_method', None)
116 ns ± 0.765 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

제가 이 접근법을 장려하는 것이 아니라, 효과가 있는 것 같습니다.

[EDIT] 메서드 이름이 지정된 클래스에 없는 경우 성능이 더욱 향상됩니다.

>>%timeit 'rubbish' in t.__dict__
65.5 ns ± 11 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

>>%timeit getattr(t, 'rubbish', None)
385 ns ± 12.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

언급URL : https://stackoverflow.com/questions/5268404/what-is-the-fastest-way-to-check-if-a-class-has-a-function-defined

반응형