"호출 가능"이란 무엇입니까?
메타 클래스가 무엇인지 분명히 알았 으므로 , 그것이 실제로 무엇을 의미하는지 알지 못하고 항상 사용하는 관련 개념이 있습니다.
모든 사람이 한 번 괄호로 실수하여 "객체를 호출 할 수 없음"예외가 발생했다고 가정합니다. 사용, 무엇보다 __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;
}
}
그것은 말한다 :
- 객체가 어떤 클래스의 인스턴스 인 경우는 호출입니다 IFF에 는이
__call__
속성을. - 다른 객체가
x
호출이다 IFFx->ob_type->tp_call != NULL
의 Desciption tp_call
분야 :
ternaryfunc tp_call
객체 호출을 구현하는 함수에 대한 선택적 포인터입니다. 객체를 호출 할 수없는 경우 NULL이어야합니다. 서명은 PyObject_Call ()과 동일합니다. 이 필드는 하위 유형으로 상속됩니다.
항상 내장 callable
함수를 사용하여 주어진 객체의 호출 가능 여부를 결정할 수 있습니다 . 또는 더 나은 방법으로 전화를 걸어 TypeError
나중에 잡을 수 있습니다. callable
Python 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
'Programing' 카테고리의 다른 글
원자 / 휘발성 / 동기화의 차이점은 무엇입니까? (0) | 2020.03.23 |
---|---|
Mockito가 논쟁에 관계없이 방법을 쓸 수 있습니까? (0) | 2020.03.23 |
JSON에서 큰 따옴표를 이스케이프 처리하는 방법 (0) | 2020.03.23 |
Access-Control-Allow-Origin 와일드 카드 하위 도메인, 포트 및 프로토콜 (0) | 2020.03.23 |
vim 줄 번호-기본적으로 어떻게 설정합니까? (0) | 2020.03.23 |