메타 클래스가 무엇인지 분명히 알았 으므로 , 그것이 실제로 무엇을 의미하는지 알지 못하고 항상 사용하는 관련 개념이 있습니다.
모든 사람이 한 번 괄호로 실수를하여 "객체를 호출 할 수 없음"예외가 발생했다고 가정합니다. 사용, 무엇보다 __init__
하고 __new__
이 피 묻은이 궁금해으로 이어질 __call__
사용할 수 있습니다.
마법 방법을 사용한 예를 포함하여 설명을 해 주시겠습니까?
메타 클래스가 무엇인지 분명히 알았 으므로 , 그것이 실제로 무엇을 의미하는지 알지 못하고 항상 사용하는 관련 개념이 있습니다.
모든 사람이 한 번 괄호로 실수를하여 "객체를 호출 할 수 없음"예외가 발생했다고 가정합니다. 사용, 무엇보다 __init__
하고 __new__
이 피 묻은이 궁금해으로 이어질 __call__
사용할 수 있습니다.
마법 방법을 사용한 예를 포함하여 설명을 해 주시겠습니까?
답변:
호출 가능은 호출 할 수있는 모든 것입니다.
내장 호출 (objects.c에서 PyCallable_Check) 검사는 인수가 하나 인 경우 :
__call__
메소드 가있는 클래스의 인스턴스 또는명명 된 방법 __call__
은 ( 문서에 따라 )
인스턴스가 함수로``호출 ''될 때 호출됩니다.
class Foo:
def __call__(self):
print 'called'
foo_instance = Foo()
foo_instance() #this is calling the __call__ method
callable
실제로 무언가를 호출 할 수 있는지 여부를 __call__
알려주고 확인하는 동안 아무 것도 알려주지 않습니다. 객체가있는 경우 o
제공 __getattribute__
하거나 __getattr__
, hasattr(o, '__call__')
사실을 반환 할 수 있습니다, 아직 o
파이썬은 건너 뛰고 있기 때문에 아직 호출되지 않습니다 __getattribute__
및 __getattr__
통화. 호출 할 수 있는지 확인하는 유일한 방법은 EAFP입니다.
callable()
를 참조하십시오 . " 이 함수는 Python 3.0에서 처음 제거 된 다음 Python 3.2로 다시 가져 왔습니다. ".
tp_call
확인됩니다. PyCallable_Check 구현을 참조하십시오 .3 줄입니다.
파이썬 소스에서 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;
}
}
그것은 말한다 :
__call__
속성을.x
호출이다 IFF x->ob_type->tp_call != NULL
의 설명 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')
def f(): ...
, 그리고 클래스는 같은 객체 class C: ...
즉, f
, ''.strip
, len
, 그리고 C
모두가 호출됩니다. __call__()
클래스에 메소드 가있는 인스턴스 는 비교적 드 rare니다.
콜 러블은 객체를 사용하여 괄호 ()를 사용하고 함수와 마찬가지로 일부 매개 변수를 전달할 수 있습니다.
함수를 정의 할 때마다 파이썬은 호출 가능한 객체를 만듭니다. 예를 들어, 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__
. 파이썬이 이것을 해결하는 방식은 제 생각에는 매우 우아합니다.
type(int).__call__(int, '10')
와 type(unicode).__call__(unicode, '10')
. 던더는 인스턴스를 통하지 않고 항상 수업에 부릅니다. 그리고 그들은 결코 메타 클래스를 거치지 않습니다. 대부분의 경우 이는 단순한 선택이지만 때로는 중요합니다.
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
>>>
파이썬에서 콜 러블은 타입에 __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
클래스의 함수 또는 메소드를 확인하는 것은 호출 가능 여부를 의미하므로 해당 함수를 호출 할 수 있습니다.
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
callable(obj.__init___)
(AttributeError에서와 같이) 추가 밑줄을하지 않는 이유는 무엇입니까? 그렇지 않다면 그 대답이 맞지 True
않습니까?
콜 러블은 __call__
특수 메소드를 구현 하므로 해당 메소드가있는 모든 오브젝트를 호출 할 수 있습니다.
__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
>>>
감사합니다. 안부, 마리스
print
함수 를 호출하면 Python은 print 유형의 객체를 만들고 해당 메소드를 호출합니다 __call__
." 파이썬은 인쇄 객체를 만들지 않습니다. 그냥에 해당하는 것을 호출합니다 type(print).__call__(print, *args, **kwargs)
. 그리고 첫 번째 문장은 의미가 없습니다. 호출 가능한 객체를 혼동하고 함수를 "호출"하는 것 같습니다.