is_callable Callbacks / Callables What is a 「callable」?

PHP: Callback / Callable 類型 - Manual https://www.php.net/manual/zh/language.types.callable.phpphp

Callback / Callable 類型

自 PHP 5.4 起可用 callable 類型指定回調類型 callback。本文檔基於一樣理由使用 callback 類型信息。html

一些函數如 call_user_func() 或 usort() 能夠接受用戶自定義的回調函數做爲參數。回調函數不止能夠是簡單函數,還能夠是對象的方法,包括靜態類方法。python

傳遞

PHP是將函數以string形式傳遞的。 能夠使用任何內置或用戶自定義函數,但除了語言結構例如:array()echoempty()eval()exit()isset()list()print 或 unset()api

一個已實例化的 object 的方法被做爲 array 傳遞,下標 0 包含該 object,下標 1 包含方法名。 在同一個類裏能夠訪問 protected 和 private 方法。app

靜態類方法也可不經實例化該類的對象而傳遞,只要在下標 0 中包含類名而不是對象。自 PHP 5.2.3 起,也能夠傳遞 'ClassName::methodName'less

除了普通的用戶自定義函數外,也可傳遞 匿名函數 給回調參數。ide

 

Example #1 回調函數示例svn

<?php 

// An example callback function
function my_callback_function() {
    echo 
'hello world!';
}

// An example callback method
class MyClass {
    static function 
myCallbackMethod() {
        echo 
'Hello World!';
    }
}

// Type 1: Simple callback
call_user_func('my_callback_function'); 

// Type 2: Static class method call
call_user_func(array('MyClass''myCallbackMethod')); 

// Type 3: Object method call
$obj = new MyClass();
call_user_func(array($obj'myCallbackMethod'));

// Type 4: Static class method call (As of PHP 5.2.3)
call_user_func('MyClass::myCallbackMethod');

// Type 5: Relative static class method call (As of PHP 5.3.0)
class {
    public static function 
who() {
        echo 
"A\n";
    }
}

class 
extends {
    public static function 
who() {
        echo 
"B\n";
    }
}

call_user_func(array('B''parent::who')); // A

// Type 6: Objects implementing __invoke can be used as callables (since PHP 5.3)
class {
    public function 
__invoke($name) {
        echo 
'Hello '$name"\n";
    }
}

$c = new C();
call_user_func($c'PHP!');
?>

 

Example #2 使用 Closure 的示例函數

<?php
// Our closure
$double = function($a) {
    return 
$a 2;
};

// This is our range of numbers
$numbers range(15);

// Use the closure as a callback here to 
// double the size of each element in our 
// range
$new_numbers array_map($double$numbers);

print 
implode(' '$new_numbers);
?>

以上例程會輸出:ui

2 4 6 8 10

Note:

在函數中註冊有多個回調內容時(如使用 call_user_func() 與 call_user_func_array()),如在前一個回調中有未捕獲的異常,其後的將再也不被調用。

 

 

Callbacks / Callables

Callbacks can be denoted by callable type hint as of PHP 5.4. This documentation used callback type information for the same purpose.

Some functions like call_user_func() or usort() accept user-defined callback functions as a parameter. Callback functions can not only be simple functions, but also object methods, including static class methods.

Passing

A PHP function is passed by its name as a string. Any built-in or user-defined function can be used, except language constructs such as:array()echoempty()eval()exit()isset()list()print or unset().

A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1. Accessing protected and private methods from within a class is allowed.

Static class methods can also be passed without instantiating an object of that class by passing the class name instead of an object at index 0. As of PHP 5.2.3, it is also possible to pass 'ClassName::methodName'.

Apart from common user-defined function, anonymous functions can also be passed to a callback parameter.

 

Example #1 Callback function examples

<?php

// An example callback function
function my_callback_function() {
    echo 
'hello world!';
}

// An example callback method
class MyClass {
    static function 
myCallbackMethod() {
        echo 
'Hello World!';
    }
}

// Type 1: Simple callback
call_user_func('my_callback_function');

// Type 2: Static class method call
call_user_func(array('MyClass''myCallbackMethod'));

// Type 3: Object method call
$obj = new MyClass();
call_user_func(array($obj'myCallbackMethod'));

// Type 4: Static class method call (As of PHP 5.2.3)
call_user_func('MyClass::myCallbackMethod');

// Type 5: Relative static class method call (As of PHP 5.3.0)
class {
    public static function 
who() {
        echo 
"A\n";
    }
}

class 
extends {
    public static function 
who() {
        echo 
"B\n";
    }
}

call_user_func(array('B''parent::who')); // A

// Type 6: Objects implementing __invoke can be used as callables (since PHP 5.3)
class {
    public function 
__invoke($name) {
        echo 
'Hello '$name"\n";
    }
}

$c = new C();
call_user_func($c'PHP!');
?>

 

Example #2 Callback example using a Closure

<?php
// Our closure
$double = function($a) {
    return 
$a 2;
};

// This is our range of numbers
$numbers range(15);

// Use the closure as a callback here to
// double the size of each element in our
// range
$new_numbers array_map($double$numbers);

print 
implode(' '$new_numbers);
?>

The above example will output:

2 4 6 8 10

Note:

Callbacks registered with functions such as call_user_func() and call_user_func_array() will not be called if there is an uncaught exception thrown in a previous callback.

 

 

PHP: Callbacks / Callables - Manual https://www.php.net/manual/en/language.types.callable.php

 

python - What is a "callable"? - Stack Overflow https://stackoverflow.com/questions/111234/what-is-a-callable

 

A callable is anything that can be called.

The built-in callable (PyCallable_Check in objects.c) checks if the argument is either:

  • an instance of a class with a __call__ method or
  • is of a type that has a non null tp_call (c struct) member which indicates callability otherwise (such as in functions, methods etc.)

The method named __call__ is (according to the documentation)

Called when the instance is ''called'' as a function

Example

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

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

 

 

 

From Python's sources 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;
    }
}

It says:

  1. If an object is an instance of some class then it is callable iff it has __call__ attribute.
  2. Else the object x is callable iff x->ob_type->tp_call != NULL

Desciption of tp_call field:

ternaryfunc tp_call An optional pointer to a function that implements calling the object. This should be NULL if the object is not callable. The signature is the same as for PyObject_Call(). This field is inherited by subtypes.

You can always use built-in callable function to determine whether given object is callable or not; or better yet just call it and catch TypeError later. callable is removed in Python 3.0 and 3.1, use callable = lambda o: hasattr(o, '__call__') or isinstance(o, collections.Callable).

Example, a simplistic cache implementation:

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

Usage:

@Cached
def ack(x, y):
    return ack(x-1, ack(x, y-1)) if x*y else (x + y + 1)

Example from standard library, file site.py, definition of built-in exit() and quit() functions:

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.3.6. 模擬可調用對象

object. __call__ ( self [args... ] )

此方法會在實例做爲一個函數被「調用」時被調用;若是定義了此方法,則 x(arg1, arg2, ...) 就至關於 x.__call__(arg1, arg2, ...) 的快捷方式。

3.3.6. Emulating callable objects

object. __call__ ( self [args... ] )

Called when the instance is 「called」 as a function; if this method is defined, x(arg1, arg2, ...) is a shorthand for x.__call__(arg1, arg2, ...).

 

 

3. Data model — Python 3.8.3 documentation https://docs.python.org/3/reference/datamodel.html#object.__call__

 

 

 

 

 

 

 

Callback / Callable 類型

自 PHP 5.4 起可用 callable 類型指定回調類型 callback。本文檔基於一樣理由使用 callback 類型信息。

一些函數如 call_user_func() 或 usort() 能夠接受用戶自定義的回調函數做爲參數。回調函數不止能夠是簡單函數,還能夠是對象的方法,包括靜態類方法。

傳遞

PHP是將函數以string形式傳遞的。 能夠使用任何內置或用戶自定義函數,但除了語言結構例如:array()echoempty()eval()exit()isset()list()print 或 unset()

一個已實例化的 object 的方法被做爲 array 傳遞,下標 0 包含該 object,下標 1 包含方法名。 在同一個類裏能夠訪問 protected 和 private 方法。

靜態類方法也可不經實例化該類的對象而傳遞,只要在下標 0 中包含類名而不是對象。自 PHP 5.2.3 起,也能夠傳遞 'ClassName::methodName'

除了普通的用戶自定義函數外,也可傳遞 匿名函數 給回調參數。

 

Example #1 回調函數示例

<?php 

// An example callback function
function my_callback_function() {
    echo 
'hello world!';
}

// An example callback method
class MyClass {
    static function 
myCallbackMethod() {
        echo 
'Hello World!';
    }
}

// Type 1: Simple callback
call_user_func('my_callback_function'); 

// Type 2: Static class method call
call_user_func(array('MyClass''myCallbackMethod')); 

// Type 3: Object method call
$obj = new MyClass();
call_user_func(array($obj'myCallbackMethod'));

// Type 4: Static class method call (As of PHP 5.2.3)
call_user_func('MyClass::myCallbackMethod');

// Type 5: Relative static class method call (As of PHP 5.3.0)
class {
    public static function 
who() {
        echo 
"A\n";
    }
}

class 
extends {
    public static function 
who() {
        echo 
"B\n";
    }
}

call_user_func(array('B''parent::who')); // A

// Type 6: Objects implementing __invoke can be used as callables (since PHP 5.3)
class {
    public function 
__invoke($name) {
        echo 
'Hello '$name"\n";
    }
}

$c = new C();
call_user_func($c'PHP!');
?>

 

Example #2 使用 Closure 的示例

<?php
// Our closure
$double = function($a) {
    return 
$a 2;
};

// This is our range of numbers
$numbers range(15);

// Use the closure as a callback here to 
// double the size of each element in our 
// range
$new_numbers array_map($double$numbers);

print 
implode(' '$new_numbers);
?>

以上例程會輸出:

2 4 6 8 10

Note:

在函數中註冊有多個回調內容時(如使用 call_user_func() 與 call_user_func_array()),如在前一個回調中有未捕獲的異常,其後的將再也不被調用。

相關文章
相關標籤/搜索