這是我在php中使用python模擬裝飾器的方法。
function call_decorator ($decorator, $function, $args, $kwargs) {
// Call the decorator and pass the function to it
$decorator($function, $args, $kwargs);
}
function testing ($args, $kwargs) {
echo PHP_EOL . 'test 1234' . PHP_EOL;
}
function wrap_testing ($func, $args, $kwargs) {
// Before call on passed function
echo 'Before testing';
// Call the passed function
$func($args, $kwargs);
// After call on passed function
echo 'After testing';
}
// Run test
call_decorator('wrap_testing', 'testing');
輸出:
Before testing
testing 1234
After testing
使用這種實現,你也可以做這樣的事情有一個匿名函數:
// Run new test
call_decorator('wrap_testing', function($args, $kwargs) {
echo PHP_EOL . 'Hello!' . PHP_EOL;
});
輸出:
Before testing
Hello!
After testing
並且最後你甚至可以做一些像這樣的事情,如果你這麼傾向。
// Run test
call_decorator(function ($func, $args, $kwargs) {
echo 'Hello ';
$func($args, $kwargs);
}, function($args, $kwargs) {
echo 'World!';
});
輸出:
Hello World!
通過以上這種結構,可以將變量傳遞給內部函數或包裝,如果需要的話。下面是一個匿名的內部函數實現:
$test_val = 'I am accessible!';
call_decorator('wrap_testing', function($args, $kwargs){
echo $args[0];
}, array($test_val));
它將工作完全一樣沒有一個匿名函數:
function test ($args, $kwargs) {
echo $kwargs['test'];
}
$test_var = 'Hello again!';
call_decorator('wrap_testing', 'test', array(), array('test' => $test_var));
最後,如果您需要修改任何包裝或內部變量wrappie,你只需要通過引用傳遞變量。
在不參考:
$test_var = 'testing this';
call_decorator(function($func, $args, $kwargs) {
$func($args, $kwargs);
}, function($args, $kwargs) {
$args[0] = 'I changed!';
}, array($test_var));
輸出:
testing this
參考:
$test_var = 'testing this';
call_decorator(function($func, $args, $kwargs) {
$func($args, $kwargs);
}, function($args, $kwargs) {
$args[0] = 'I changed!';
// Reference the variable here
}, array(&$test_var));
輸出:
I changed!
這就是我的全部,現在,它是一個在很多情況下非常有用,你甚至可以多次包裝他們,如果你想。
你Wrap_A的例子是有點誤導人誰不已經知道如何Python的裝飾器的工作,因爲你Wrap_A的實施顯式地引用A.一個裝飾的想法是,你可以裝飾任何函數,但在你的例子顯然不能使用'Wrap_A'來包裝其他一些函數'B'。你介意我是否編輯了你的問題,讓它更精確地表示裝飾是什麼功能? – 2014-01-05 15:11:37