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


310

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

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

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


답변:


308

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

내장 호출 (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

6
내장 콜 러블은 파이썬 3.0에서 제거되어
Eli Courtwright

13
@Eli : 흠, 그것은 매우 나쁜 움직임 인 것 같습니다. callable실제로 무언가를 호출 할 수 있는지 여부를 __call__알려주고 확인하는 동안 아무 것도 알려주지 않습니다. 객체가있는 경우 o제공 __getattribute__하거나 __getattr__, hasattr(o, '__call__')사실을 반환 할 수 있습니다, 아직 o파이썬은 건너 뛰고 있기 때문에 아직 호출되지 않습니다 __getattribute____getattr__통화. 호출 할 수 있는지 확인하는 유일한 방법은 EAFP입니다.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

49
@Longpoke : 레코드에 대해서는 Python 3.x 의 설명서callable() 를 참조하십시오 . " 이 함수는 Python 3.0에서 처음 제거 된 다음 Python 3.2로 다시 가져 왔습니다. ".
Tadeck

파이썬 3.8에서는 존재 여부 만 tp_call확인됩니다. PyCallable_Check 구현을 참조하십시오 .3 줄입니다.
Michele Piccolini

84

파이썬 소스에서 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

의 설명 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')

10
호출 방법에 대한 예제는 캐싱 및 데코레이터를위한 레시피와 혼합되어 호출
Florian Bösch

3
JF Sebastian은 또한 최소한의 다른 곳에서 복사하여 붙여 넣은 더 많은 예제를 제출하는 것이 도움이되지 않습니다.
Florian Bösch

20
@JF Sebastian : 더 실물 같은 예가 더 좋은 BS입니다. 예를 들어 울면서 생생한 코드를 보여줄 수 있습니다. 간단한 예제도 효과가 있으며,주의가 산만하지 않기 때문에 무언가를 설명하는 것이 좋습니다.
Florian Bösch

5
호출 가능 항목에 대해 설명하고 있지만 호출 가능 오브젝트를 사용하여 데코레이터를 정의하는 방법에 대한 예제를 제공했습니다. 나는의 일반적인 사용 알고 호출 하지만 이것은 단지 호출하고 사용하는 방법을 알고 싶은 독자를 혼란스럽게 할 수 호출을 . @Florian Bösch의 답변을 선호합니다.
KFL

2
@Kay : @Florian Bösch의 답변 (현재 형식)도 좋아합니다. btw, 데코레이터는 "호출 가능"의 일반적인 사용법 이 아닙니다 . 가장 일반적인 "callables"은 다음과 같은 기능 / 방법이 있습니다 def f(): ..., 그리고 클래스는 같은 객체 class C: ...즉, f, ''.strip, len, 그리고 C모두가 호출됩니다. __call__()클래스에 메소드 가있는 인스턴스 는 비교적 드 rare니다.
jfs

37

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

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

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

func = a()

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

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


37

거꾸로 설명하겠습니다 :

이걸 고려하세요...

foo()

...의 구문 설탕으로 :

foo.__call__()

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

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

int('10')
unicode(10)

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

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

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


당신은 본질적으로 일을하는지 type(int).__call__(int, '10')type(unicode).__call__(unicode, '10'). 던더는 인스턴스를 통하지 않고 항상 수업에 부릅니다. 그리고 그들은 결코 메타 클래스를 거치지 않습니다. 대부분의 경우 이는 단순한 선택이지만 때로는 중요합니다.
Mad Physicist

11

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

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

[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
>>> 

9

__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)

7

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


5

파이썬에서 콜 러블은 타입에 __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

3

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

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

1
당신은시겠습니까 callable(obj.__init___)(AttributeError에서와 같이) 추가 밑줄을하지 않는 이유는 무엇입니까? 그렇지 않다면 그 대답이 맞지 True않습니까?
Mad Physicist

2

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


2

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


__call__클래스가 그러한 메소드를 정의하지 않으면 정의한 인스턴스를 호출 할 수 없습니다.
Mad Physicist

2

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

>>> 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
>>>

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


1
여기에있는 정보 중 일부가 잘못되었습니다. 예를 들어 " print함수 를 호출하면 Python은 print 유형의 객체를 만들고 해당 메소드를 호출합니다 __call__." 파이썬은 인쇄 객체를 만들지 않습니다. 그냥에 해당하는 것을 호출합니다 type(print).__call__(print, *args, **kwargs). 그리고 첫 번째 문장은 의미가 없습니다. 호출 가능한 객체를 혼동하고 함수를 "호출"하는 것 같습니다.
Mad Physicist
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.