"कॉल करने योग्य" क्या है?


310

अब जब यह स्पष्ट हो गया है कि मेटाक्लास क्या है , तो एक संबद्ध अवधारणा है कि मैं हर समय यह जानने के बिना उपयोग करता हूं कि इसका वास्तव में क्या मतलब है।

मुझे लगता है कि हर किसी ने एक बार कोष्ठक के साथ एक गलती की है, जिसके परिणामस्वरूप "ऑब्जेक्ट कॉल करने योग्य नहीं है" अपवाद है। क्या अधिक है, का उपयोग कर __init__और __new__आश्चर्य करने के लिए नेतृत्व क्या इस खूनी के __call__लिए इस्तेमाल किया जा सकता है।

क्या आप मुझे जादू की विधि के साथ उदाहरण सहित कुछ स्पष्टीकरण दे सकते हैं?


10
संबंधित: पायथन
इंटर्न

जवाबों:


308

एक कॉल करने योग्य कुछ भी है जिसे कॉल किया जा सकता है।

बिल्ट-इन प्रतिदेय (objects.c में PyCallable_Check) जांच करता है कि तर्क या तो है:

  • __call__विधि के साथ वर्ग का एक उदाहरण या
  • एक प्रकार का है जिसमें एक अशक्त tp_call (c संरचना) सदस्य है जो कॉलिबिलिटी को इंगित करता है अन्यथा (जैसे कि फ़ंक्शन, विधियों आदि में)

नामित विधि __call__( प्रलेखन के अनुसार ) है

फंक्शन के रूप में '' '' कहा जाता है जब कॉल किया जाता है

उदाहरण

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

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

6
ध्यान दें कि कॉल के
बिलियन कॉलेबल

13
@ एलि: हम्म जो एक बहुत ही बुरे कदम की तरह लगता है । callableवास्तव में आपको बताता है कि क्या कुछ कॉल करने योग्य है या नहीं, जबकि जाँच के लिए __call__आपको कुछ भी नहीं बताता है; यदि कोई वस्तु oप्रदान करता है __getattribute__या __getattr__, hasattr(o, '__call__')सत्य लौटा सकता है, तब oभी अभी भी कॉल करने योग्य नहीं होगा , क्योंकि पायथन स्काइप __getattribute__और __getattr__कॉल के लिए। यह देखने के लिए एकमात्र वास्तविक तरीका है कि क्या कुछ कॉल करने योग्य है, इस प्रकार ईएएफपी है।
L --o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e

49
@Longpoke: सिर्फ रिकॉर्ड के लिए callable(), पाइथन 3.x के लिए प्रलेखन देखें : " यह फ़ंक्शन पहले पायथन 3.0 में हटा दिया गया था और फिर पायथन 3.2 में वापस लाया गया। "
टाडेक

यह अजगर 3.8 में लगता है केवल उपस्थिति की tp_callजाँच की जाती है। PyCallable_Check का कार्यान्वयन देखें , यह 3 लाइनें है।
मिशेल पिकोलिनी

84

पायथन के स्रोतों से ऑब्जेक्ट ।.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बाद में पकड़ लें । callableपायथन 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
मुझे कॉल विधि अत्यधिक मिसलीडिंग के लिए उदाहरण लगती है क्योंकि यह इसे कैशिंग और डेकोरेटर्स के लिए एक नुस्खा के साथ मिलाता है, जो कॉल
जोड़ता है

3
JF सेबस्टियन, आपके द्वारा कॉपी और पेस्ट किए गए अधिक उदाहरणों को भी कहीं और जमा करना, जो न्यूनतम नहीं हैं, मदद नहीं करता है।
फ्लोरियन बॉश

20
@ जेएफ सेबस्टियन: यह बीएस है कि अधिक जीवन की तरह के उदाहरण बेहतर हैं। मैं आपको जीवन के समान कोड दिखा सकता हूं जो आपको एक उदाहरण के रूप में रोएगा। सरल उदाहरण भी काम करते हैं, और वे कुछ को चित्रित करने के लिए बेहतर काम करते हैं क्योंकि वे विचलित नहीं करते हैं।
फ्लोरियन बॉश

5
आप बता रहे हैं कि कॉल करने योग्य क्या है, लेकिन आपने एक उदाहरण दिया कि कैसे कॉल करने योग्य वस्तुओं का उपयोग एक डेकोरेटर को परिभाषित करने के लिए किया जाता है। मैं जानता हूँ कि यह एक विशिष्ट उपयोग है प्रतिदेय लेकिन यह पाठकों जो सिर्फ पता है कि प्रतिदेय है और कैसे उपयोग करना चाहते हैं भ्रमित कर सकते हैं प्रतिदेय । मुझे @Florian Bösch का जवाब पसंद है।
केएफएल

2
@Kay: मुझे @Florian Bösch का उत्तर (अपने वर्तमान रूप में) भी पसंद है। btw, एक डेकोरेटर "कॉलेबल" का एक विशिष्ट उपयोग नहीं है। सबसे विशिष्ट "callables" इस तरह के रूप में कार्य करता / तरीके हैं def f(): ..., और वर्ग के रूप में इस तरह की वस्तुओं class C: ...यानी, f, ''.strip, len, और Cसभी प्रतिदेय हैं। ऐसे उदाहरण __call__()जिनकी कक्षा में एक विधि है, अपेक्षाकृत दुर्लभ हैं।
jfs

37

एक कॉल करने योग्य एक ऑब्जेक्ट है जो आपको गोल कोष्ठक () का उपयोग करने की अनुमति देता है और अंततः कार्यों की तरह कुछ मापदंडों को पारित करता है।

हर बार जब आप फ़ंक्शन को परिभाषित करते हैं तो अजगर एक कॉल करने योग्य वस्तु बनाता है। उदाहरण में, आप इन तरीकों से फ़ंक्शन फ़ंक को परिभाषित कर सकते हैं (यह वही है):

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

func = a()

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

आप इस विधि का उपयोग doit या run जैसी विधियों के बजाय कर सकते हैं , मुझे लगता है कि यह obj.do () की तुलना में 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')। डंडर्स को हमेशा उनकी कक्षा में बुलाया जाता है, उदाहरण के माध्यम से नहीं। और वे कभी भी मेटाक्लस के माध्यम से नहीं जाते हैं। ज्यादातर मामलों के लिए यह सिर्फ एक निपिक है, लेकिन यह कभी-कभी मायने रखता है।
मैड फिजिसिस्ट

11

एक Callable एक ऑब्जेक्ट है जिसमें __call__विधि है। इसका मतलब है कि आप कॉल करने योग्य कार्यों को नकली कर सकते हैं या आंशिक फ़ंक्शन अनुप्रयोग जैसी साफ-सुथरी चीजें कर सकते हैं जहां आप एक फ़ंक्शन लेते हैं और ऐसा कुछ जोड़ते हैं जो इसे बढ़ाता है या कुछ मापदंडों में भरता है, कुछ ऐसा लौटाता है जिसे बदले में कहा जा सकता है ( कार्यात्मक प्रोग्रामिंग हलकों में करी के रूप में जाना जाता है) )।

कुछ टाइपोग्राफिक त्रुटियों में दुभाषिया का प्रयास होगा कि आप कुछ ऐसा करने का प्रयास न करें, जैसे कि (उदाहरण के लिए) एक स्ट्रिंग। यह उन त्रुटियों का उत्पादन कर सकता है जहां दुभाषिया एक गैर-कॉल करने योग्य एप्लिकेशन को निष्पादित करने का प्रयास करता है। आप नीचे दिए गए प्रतिलेख की तरह कुछ करके एक अजगर दुभाषिया में ऐसा होते देख सकते हैं।

[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

काफी बस, एक "कॉल करने योग्य" एक ऐसी चीज है जिसे एक विधि की तरह कहा जा सकता है। अंतर्निहित फ़ंक्शन " कॉल करने योग्य ()" आपको बताएगा कि क्या कुछ कॉल करने योग्य प्रतीत होता है, जैसा कि कॉल संपत्ति के लिए जाँच करेगा । फ़ंक्शंस कॉल करने योग्य होते हैं क्योंकि क्लास हैं, क्लास इंस्टेंसेस कॉल करने योग्य हो सकते हैं। इस बारे में अधिक देखें यहां और यहां


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___)एक अतिरिक्त अंडरस्कोर नहीं है (जैसा कि एट्रीब्यूट्री में)? यदि ऐसा नहीं होता है, तो क्या आप सुनिश्चित हैं कि उत्तर Trueउस एक के लिए नहीं है ?
मैड फिजिसिस्ट

2

यह ऐसा कुछ है जिसे आप "(args)" के बाद रख सकते हैं और काम करने की उम्मीद कर सकते हैं। एक कॉल करने योग्य आमतौर पर एक विधि या एक वर्ग है। तरीकों को बुलाया जाता है, कक्षाएं तुरंत हो जाती हैं।


2

callables __call__विशेष विधि को लागू करता है इसलिए इस तरह की विधि के साथ कोई भी वस्तु कॉल करने योग्य है।


__call__यदि आप इस तरह की पद्धति को परिभाषित नहीं करते हैं, तो आप जिस पर परिभाषित करते हैं, वह कॉल करने योग्य नहीं होगा।
मैड फिजिसिस्ट

2

कॉल करने योग्य एक विधि कॉल के साथ "बिल्ड-इन फ़ंक्शन या विधि" का एक प्रकार या वर्ग है

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

उदाहरण: प्रिंट एक कॉल करने योग्य वस्तु है। एक बिल्ड-इन फ़ंक्शन के साथ __call__ जब आप प्रिंट फ़ंक्शन को लागू करते हैं, तो पायथन टाइप प्रिंट की एक वस्तु बनाता है और यदि कोई हो तो पैरामीटर __call__ को पारित करने की अपनी विधि को आमंत्रित करता है ।

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

धन्यवाद। सादर, मारीस


1
यहाँ जानकारी में से कुछ सीधे गलत है। उदाहरण के लिए "जब आप printफ़ंक्शन को लागू करते हैं, तो पायथन टाइप प्रिंट की एक वस्तु बनाता है और इसकी विधि को आमंत्रित करता है __call__"। अजगर एक प्रिंट ऑब्जेक्ट नहीं बनाता है। यह बस के बराबर कुछ कहता है type(print).__call__(print, *args, **kwargs)। और पहला वाक्य ज्यादा मायने नहीं रखता है। आप एक कॉल करने योग्य ऑब्जेक्ट और "कॉल करने योग्य" फ़ंक्शन को भ्रमित करते हुए दिखाई देते हैं।
मैड फिजिसिस्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.