Что такое "вызываемый" в Python?

Теперь понятно что такое метакласс-это, есть связанная концепция, которую я использую все время, не зная, что это на самом деле означает.

Я полагаю, что все когда-то сделали ошибку с круглыми скобками, в результате чего исключение "объект не вызывается". Более того, используя __init__ и __new__ интересно, что это за чертов __call__ можно использовать для.

не могли бы вы дать мне некоторые пояснения, в том числе примеры с магическим методом ?

12 ответов


вызываемый-это все, что можно назвать.

на встроенный вызвать (PyCallable_Check в объектах.c) проверяет, является ли аргумент является либо:

  • экземпляр класса с __call__ способ или
  • имеет тип, который имеет не null tp_call (C struct) член, который указывает на вызываемость в противном случае (например, в функциях, методах и т. д.)

метод с именем __call__ is (согласно документации)

вызывается, когда экземпляр "вызывается" как функция

пример

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

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

из источников Python .

  • другого объекта 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) 
    

    пример из стандартной библиотеки, file 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')
    

    вызываемый объект позволяет использовать круглые скобки () и в конечном итоге передавать некоторые параметры, как и функции.

    каждый раз, когда вы определяете функцию Python создает вызываемый объект. Например, вы можете определить функцию func таким образом (это то же самое):

    class a(object):
        def __call__(self, *args):
            print 'Hello'
    
    func = a()
    
    # or ... 
    def func(*args):
        print 'Hello'
    

    вы можете использовать этот метод вместо метода как doit или run, Я думаю, что просто более ясно видеть obj (), чем параметр obj.doit ()


    позвольте мне объяснить назад:

    рассмотреть этот вопрос...

    foo()
    

    ... как синтаксический сахар для:

    foo.__call__()
    

    здесь foo может быть любой объект, который реагирует на __call__. Когда я говорю любой объект, я имею в виду: встроенные типы, ваши собственные классы и их экземпляры.

    в случае встроенных типов, когда вы пишете:

    int('10')
    unicode(10)
    

    вы по существу делаете:

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

    вот почему у вас нет foo = new int в Python: вы просто сделайте объект class возвращающим экземпляр его на __call__. То, как Python решает это, на мой взгляд, очень элегантно.


    вызываемым является объект, который имеет __call__ метод. Это означает, что вы можете подделать вызываемые функции или делать аккуратные вещи, такие как Применение Частичной Функции где вы берете функцию и добавляете что-то, что улучшает ее или заполняет некоторые параметры, возвращая что-то, что можно вызвать в свою очередь (известный как карринг в функциональных кругах программирования).

    некоторые типографские ошибки будут иметь интерпретатор, пытающийся вызвать то, что вы сделали не намереваться, например (например) строку. Это может привести к ошибкам, когда интерпретатор пытается выполнить не вызываемое приложение. Вы можете увидеть это в интерпретаторе python, сделав что-то вроде транскрипта ниже.

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

    в Python вызываемым является объект, тип которого имеет __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
    

    Callable-это тип или класс "встроенной функции или метода" с помощью метода вызов

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

    пример: печати является вызываемым объектом. Со встроенной функцией __call__ При вызове печати функция, Python создает "объект" в печать типа и вызывает его метод __call__ передача параметров, если таковые имеются.

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

    спасибо. С уважением, Марис!--5-->


    callables реализации __call__ специальный метод, поэтому любой объект с таким методом вызывается.