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

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

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

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

Ответ 1

Вызываемым является все, что можно назвать.

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

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

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

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

пример

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

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

Ответ 2

Из источников Python 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')

Ответ 3

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

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

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

func = a()

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

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

Ответ 4

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

Рассмотрим это...

foo()

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

foo.__call__()

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

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

int('10')
unicode(10)

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

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

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

Ответ 5

A Callable - это объект, который имеет метод __call__. Это означает, что вы можете подделывать вызываемые функции или делать аккуратные вещи, например Partial Function Application, где вы берете функцию и добавляете что-то, что улучшает ее или заполняет некоторые из параметры, возвращающие то, что может быть вызвано по очереди (известный как Currying в кругах функционального программирования).

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

[[email protected] ~]$ 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
>>> 

Ответ 6

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

Ответ 7

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

Ответ 8

В 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

Ответ 9

Это то, что вы можете положить "(args)" после и ожидать, что он будет работать. Вызываемым обычно является метод или класс. Методы получают вызываемые, классы получают экземпляр.

Ответ 10

Чтобы проверить функцию или метод класса, вызывается или нет, это значит, что мы можем вызвать эту функцию.

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

Ответ 11

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

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

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

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

Спасибо. С Уважением, Maris

Ответ 12

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

Ответ 13

Хорошие примеры здесь.

Ответ 14

чтобы узнать, что объект может быть вызван или не попробовать это

x=234
for i in dir(x):
    if i.startswith("__call__"):
        print i

здесь не будет выхода.

def add(x,y):
    return x+y
for i in dir(add):
    if i.startswith("__call__"):
        print i
>>>__call__