Programing

"호출 가능"이란 무엇입니까?

lottogame 2020. 3. 23. 08:02
반응형

"호출 가능"이란 무엇입니까?


메타 클래스가 무엇인지 분명히 알았 으므로 , 그것이 실제로 무엇을 의미하는지 알지 못하고 항상 사용하는 관련 개념이 있습니다.

모든 사람이 한 번 괄호로 실수하여 "객체를 호출 할 수 없음"예외가 발생했다고 가정합니다. 사용, 무엇보다 __init__하고 __new__이 피 묻은이 궁금해으로 이어질 __call__사용할 수 있습니다.

마법 방법을 사용한 예제를 포함하여 몇 가지 설명을 해 주시겠습니까?


호출 가능은 호출 할 수있는 모든 것입니다.

내장 호출 (objects.c에서 PyCallable_Check) 검사는 인수가 하나 인 경우 :

  • __call__메소드 가있는 클래스의 인스턴스 또는
  • 함수, 메소드 등에서 호출 가능성을 나타내는 널이 아닌 tp_call (c struct) 멤버 가있는 유형입니다 .

명명 된 방법 __call__은 ( 문서에 따라 )

인스턴스가 함수로``호출 ''될 때 호출됩니다.

class Foo:
  def __call__(self):
    print 'called'

foo_instance = Foo()
foo_instance() #this is calling the __call__ method

파이썬 소스에서 object.c :

/* Test whether an object can be called */

int
PyCallable_Check(PyObject *x)
{
    if (x == NULL)
        return 0;
    if (PyInstance_Check(x)) {
        PyObject *call = PyObject_GetAttrString(x, "__call__");
        if (call == NULL) {
            PyErr_Clear();
            return 0;
        }
        /* Could test recursively but don't, for fear of endless
           recursion if some joker sets self.__call__ = self */
        Py_DECREF(call);
        return 1;
    }
    else {
        return x->ob_type->tp_call != NULL;
    }
}

그것은 말한다 :

  1. 객체가 어떤 클래스의 인스턴스 인 경우는 호출입니다 IFF에 는이 __call__속성을.
  2. 다른 객체가 x호출이다 IFF x->ob_type->tp_call != NULL

의 Desciption tp_call분야 :

ternaryfunc tp_call객체 호출을 구현하는 함수에 대한 선택적 포인터입니다. 객체를 호출 할 수없는 경우 NULL이어야합니다. 서명은 PyObject_Call ()과 동일합니다. 이 필드는 하위 유형으로 상속됩니다.

항상 내장 callable함수를 사용하여 주어진 객체의 호출 가능 여부를 결정할 수 있습니다 . 또는 더 나은 방법으로 전화를 걸어 TypeError나중에 잡을 수 있습니다. callablePython 3.0 및 3.1에서 제거되면 callable = lambda o: hasattr(o, '__call__')또는을 사용하십시오 isinstance(o, collections.Callable).

간단한 캐시 구현 예 :

class Cached:
    def __init__(self, function):
        self.function = function
        self.cache = {}

    def __call__(self, *args):
        try: return self.cache[args]
        except KeyError:
            ret = self.cache[args] = self.function(*args)
            return ret    

용법:

@Cached
def ack(x, y):
    return ack(x-1, ack(x, y-1)) if x*y else (x + y + 1) 

표준 라이브러리, 파일 site.py, 내장 exit()quit()함수 정의의 :

class Quitter(object):
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return 'Use %s() or %s to exit' % (self.name, eof)
    def __call__(self, code=None):
        # Shells like IDLE catch the SystemExit, but listen when their
        # stdin wrapper is closed.
        try:
            sys.stdin.close()
        except:
            pass
        raise SystemExit(code)
__builtin__.quit = Quitter('quit')
__builtin__.exit = Quitter('exit')

callable은 객체를 사용하여 둥근 괄호 ()를 사용하고 함수와 마찬가지로 일부 매개 변수를 전달할 수 있습니다.

함수를 정의 할 때마다 파이썬은 호출 가능한 객체를 만듭니다. 예를 들어, func 함수 를 다음과 같이 정의 할 수 있습니다 (동일 함).

class a(object):
    def __call__(self, *args):
        print 'Hello'

func = a()

# or ... 
def func(*args):
    print 'Hello'

doit 또는 run 과 같은 메소드 대신이 메소드를 사용할 수 있습니다 .obj.doit ()보다 obj ()를 보는 것이 더 분명하다고 생각합니다


거꾸로 설명하겠습니다 :

이걸 고려하세요...

foo()

...의 구문 설탕으로 :

foo.__call__()

foo응답하는 객체가 어디에 있을 수 있습니다 __call__. 객체를 말하면 내장 유형, 자신의 클래스 및 인스턴스입니다.

내장 유형의 경우 다음을 쓸 때

int('10')
unicode(10)

당신은 본질적으로하고 있습니다 :

int.__call__('10')
unicode.__call__(10)

그렇기 때문에 foo = new int파이썬 에는없는 이유가 있습니다 . 클래스 객체가에 대한 인스턴스를 반환하도록하십시오 __call__. 파이썬이 이것을 해결하는 방식은 제 생각에는 매우 우아합니다.


Callable은 __call__메소드 가있는 객체입니다 . 즉, 호출 가능한 함수를 가짜로 만들거나 부분 함수 응용 프로그램 과 같이 깔끔한 기능 을 수행하여 함수를 가져 와서 기능을 향상 시키거나 일부 매개 변수를 채우는 함수를 추가하여 차례로 호출 할 수있는 것을 반환 할 수 있습니다 ( 기능 프로그래밍 서클의 Curry 라고 함) ).

특정 인쇄상의 오류로 인해 인터프리터가 문자열과 같이 의도하지 않은 것을 호출하려고 할 수 있습니다. 인터프리터가 호출 할 수없는 응용 프로그램을 실행하려고하면 오류가 발생할 수 있습니다. 아래의 스크립트와 같은 작업을 수행하면 파이썬 인터프리터에서 이런 일이 발생하는 것을 볼 수 있습니다.

[nigel@k9 ~]$ python
Python 2.5 (r25:51908, Nov  6 2007, 15:55:44) 
[GCC 4.1.2 20070925 (Red Hat 4.1.2-27)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 'aaa'()    # <== Here we attempt to call a string.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
>>> 

간단히 말해서 "호출 가능"은 메소드처럼 호출 될 수있는 것입니다. 내장 함수 "callable ()"은 호출 속성을 확인할 때 호출 가능한 것으로 표시되는지 여부를 알려줍니다 . 클래스와 마찬가지로 함수를 호출 할 수 있으며 클래스 인스턴스를 호출 할 수 있습니다. 이에 대한 자세한 내용은 여기여기를 참조 하십시오 .


__call__ 모든 객체를 함수로 호출 할 수있게합니다.

이 예는 8을 출력합니다.

class Adder(object):
  def __init__(self, val):
    self.val = val

  def __call__(self, val):
    return self.val + val

func = Adder(5)
print func(3)

파이썬에서 콜 러블은 타입에 __call__메소드 가있는 객체입니다 :

>>> class Foo:
...  pass
... 
>>> class Bar(object):
...  pass
... 
>>> type(Foo).__call__(Foo)
<__main__.Foo instance at 0x711440>
>>> type(Bar).__call__(Bar)
<__main__.Bar object at 0x712110>
>>> def foo(bar):
...  return bar
... 
>>> type(foo).__call__(foo, 42)
42

저것과 같이 쉬운 :)

이것은 물론 오버로드 될 수 있습니다 :

>>> class Foo(object):
...  def __call__(self):
...   return 42
... 
>>> f = Foo()
>>> f()
42

"(args)"뒤에 넣을 수 있고 작동 할 것으로 예상됩니다. 콜 러블은 일반적으로 메소드 또는 클래스입니다. 메소드가 호출되고 클래스가 인스턴스화됩니다.


클래스의 함수 또는 메소드를 확인하는 것은 호출 가능 여부를 의미하므로 해당 함수를 호출 할 수 있습니다.

Class A:
    def __init__(self,val):
        self.val = val
    def bar(self):
        print "bar"

obj = A()      
callable(obj.bar)
True
callable(obj.__init___)
False
def foo(): return "s"
callable(foo)
True
callable(foo())
False

콜 러블은 __call__특수 메소드를 구현 하므로 해당 메소드가있는 모든 오브젝트를 호출 할 수 있습니다.


호출 가능은 메소드 호출 이있는 "빌드 인 함수 또는 메소드"의 유형 또는 클래스입니다.

>>> type(callable)
<class 'builtin_function_or_method'>
>>>

예 : print 는 호출 가능한 객체입니다. 내장 함수 __call__ 사용 print 함수 를 호출하면 Python은 print 유형객체를 생성하고 __call__ 메소드를 호출 하여 매개 변수를 전달합니다 (있는 경우).

>>> type(print)
<class 'builtin_function_or_method'>
>>> print.__call__(10)
10
>>> print(10)
10
>>>

감사합니다. 안부, 마리스

참고 URL : https://stackoverflow.com/questions/111234/what-is-a-callable

반응형