একটি "আহ্বানযোগ্য" কী?


310

একটি মেটাগ্লাস কী তা এখন এটি স্পষ্ট হয়ে গেছে , একটি যুক্ত ধারণা রয়েছে যা এর সত্যিকার অর্থ কী তা আমি না জেনে আমি সমস্ত সময় ব্যবহার করি।

আমি মনে করি প্রত্যেকে প্যারেনেসিসিসের সাথে একবার ভুল করে ফেলেছে, যার ফলে একটি "অবজেক্ট কল করা যায় না" ব্যতিক্রম। আরও কী, ব্যবহার করে __init__এবং __new__এই রক্তাক্তটির __call__জন্য কী ব্যবহার করা যেতে পারে তা অবাক করে ।

আপনি কি আমাকে কিছু ব্যাখ্যা দিতে পারেন, যাদু পদ্ধতির উদাহরণ সহ?


উত্তর:


308

কলযোগ্য এমন কিছু যা বলা যেতে পারে।

বিল্ট-ইন callable (objects.c মধ্যে PyCallable_Check) চেক যদি যুক্তি পারেন হল:

  • একটি __call__পদ্ধতি বা সহ শ্রেণীর উদাহরণ or
  • এমন একটি ধরণের যা একটি নন টিপ_ক্যাল (সি স্ট্রাক্ট) সদস্য রয়েছে যা কল্যাবিলিটি অন্যথায় নির্দেশ করে (যেমন ফাংশন, পদ্ধতি ইত্যাদিতে)

নাম দেওয়া পদ্ধতিটি __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̲̳̳

48
@ লংপোক: কেবলমাত্র রেকর্ডের জন্য, দয়া করে পাইথন ৩.x এর জন্য ডকুমেন্টেশনcallable() দেখুন : " এই ফাংশনটি প্রথমে পাইথন ৩.০ এ সরানো হয়েছিল এবং তারপরে পাইথন ৩.২-এ ফিরিয়ে আনা হয়েছে। "
টেডেক

অজগর 3.8 এ মনে হয় কেবল উপস্থিতি tp_callপরীক্ষা করা হয়। পাইকল্যাবল_চেক বাস্তবায়ন দেখুন , এটি 3 লাইন lines
মিশেল পিকোলিনি

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. যদি কোনও বস্তুটি কোনও শ্রেণীর উদাহরণ হয় তবে যদি এটির __call__বৈশিষ্ট্য থাকে তবে তা কলযোগ্য ।
  2. অন্য বস্তুর xcallable হয় iff x->ob_type->tp_call != NULL

এর Desciption tp_callক্ষেত্র :

ternaryfunc tp_callকোনও ক্রিয়াকলাপের জন্য একটি alচ্ছিক পয়েন্টার যা বস্তুকে কল করার জন্য প্রয়োগ করে। যদি বস্তুটি কলযোগ্য না হয় তবে এটি NULL হওয়া উচিত। স্বাক্ষর পিওবজেক্ট_ক্যাল () এর মতো। এই ক্ষেত্রটি সাব-টাইপ দ্বারা উত্তরাধিকারসূত্রে প্রাপ্ত।

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
জেএফ সেবাস্তিয়ান, আপনি অনুলিপি করে এমন আরও কয়েকটি উদাহরণও লিখেছেন যা অন্য কোথাও থেকে আটকানো হয়েছে যা ন্যূনতম নয়, সেগুলি সহায়তা করে না।
ফ্লোরিয়ান বুশ

20
@ জেএফ সেবাস্তিয়ান: এটি জীবনের চেয়ে আরও ভালো উদাহরণের চেয়ে ভাল BS আমি আপনাকে লাইফ-কোডের মতো কোডটি প্রদর্শন করতে পারি যা আপনাকে উদাহরণ হিসাবে কেঁদে ফেলবে। সাধারণ উদাহরণগুলিও কাজ করে এবং কোনও কিছু চিত্রিত করার জন্য তারা আরও ভাল কাজ করে কারণ তারা বিভ্রান্ত হয় না।
ফ্লোরিয়িয়ান B Sepsch

5
আপনি কলযোগ্য কী তা ব্যাখ্যা করছেন, তবে আপনি কীভাবে ডেকরেটারের সংজ্ঞা দেওয়ার জন্য কলযোগ্য বস্তুগুলি ব্যবহার করবেন তা একটি উদাহরণ দিয়েছিলেন। আমি জানি এটা একটি আদর্শ ব্যবহার এর callable কিন্তু এই পাঠক যারা শুধু জানতে কি callable এবং কিভাবে ব্যবহার করতে চান গুলান পারেন callable । আমি @ ফ্লোরিয়ান বুশের উত্তর পছন্দ করব।
কেএফএল

2
@ কে: আমি @ ফ্লোরিয়ান বুশের উত্তরটিও (এটি বর্তমান আকারে) পছন্দ করি। বিটিডব্লিউ, একটি ডেকরেটর একটি "কলযোগ্য" এর সাধারণ ব্যবহার নয় । অধিকাংশ সাধারণত "callables" যেমন ফাংশন / পদ্ধতি def f(): ..., এবং শ্রেণী হিসেবে যেমন বস্তুর class C: ...অর্থাত, f, ''.strip, len, এবং Cসব callable হয়। উদাহরণস্বরূপ যেগুলির __call__()ক্লাসে একটি পদ্ধতি রয়েছে সেগুলি তুলনামূলকভাবে বিরল।
jfs

37

কলযোগ্য একটি বস্তু আপনাকে বৃত্তাকার প্রথম বন্ধনী () ব্যবহার করতে এবং শেষ পর্যন্ত কিছু প্যারামিটারগুলি যেমন ফাংশনের মতো পাস করার অনুমতি দেয়।

প্রতিবার আপনি কোনও ফাংশন সংজ্ঞায়িত করে অজগর একটি কলযোগ্য বস্তু তৈরি করে। উদাহরণস্বরূপ, আপনি এই পদ্ধতিতে ফাংশন ফানকে সংজ্ঞায়িত করতে পারেন (এটি একই)

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

func = a()

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

ডোয়েট বা রান করার মতো পদ্ধতির পরিবর্তে আপনি এই পদ্ধতিটি ব্যবহার করতে পারেন , আমি মনে করি এটি আপত্তি () (অ্যাজেক্ট.ডোইট () এর চেয়ে দেখতে আরও স্পষ্ট clear


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

কলযোগ্য এমন একটি উপাদান যা __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

এটি এমন কিছু যা আপনি পরে "(আরগস)" রাখতে পারেন এবং এটি কাজ করার আশা করে। কলযোগ্য সাধারণত একটি পদ্ধতি বা শ্রেণি হয়। পদ্ধতিগুলি কল করা হয়, ক্লাসগুলি তাত্ক্ষণিকভাবে আসে।


2

কলযোগ্যরা __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)। এবং প্রথম বাক্যটি খুব একটা বোঝায় না। আপনি কলযোগ্য বস্তুকে বিভ্রান্ত করছেন এবং ফাংশনটি "কল "যোগ্য বলে মনে হচ্ছে।
ম্যাড পদার্থবিজ্ঞানী
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.