如果我不知道包装函数的名称,是否可以使用python装饰器来标记方法,并将其用于以后的使用?
以下是示例,我不知道method_with_custom_name的名称:
@run_this_method
def method_with_custom_name(my_arg):
return "The args is: " + my_arg
def _init_and_run():
# Here, I want to get and call method_with_custom_name
# but I don't know it's name,
# so the next line isn't valid.
return run_this_method()(my_arg_value)
def run_this_method(m):
def w(my_arg):
_do_some_magic(my_arg, m)
return w
def _do_some_magic(callback_arg, callback):
if some_checks():
callback(callback_arg)
那么如何获得包含@run_this_method
答案 0 :(得分:2)
如果需要跟踪装饰器修饰的所有函数和方法,则需要创建全局变量来注册所有这些函数和方法。我修改了您的代码:
functions_registry
您可以创建用作装饰器的类,并在实体字段中注册函数,而不是使用全局变量class FunDecorator:
def __init__(self):
self.registry = []
def __call__(self, m):
"This method is called when some method is decorated"
self.registry.append(m) #Add function/method to the registry
def w(my_arg):
_do_some_magic(my_arg, m)
return w
run_this_method = FunDecorator() #Create class instance to be used as decorator
@run_this_method
def method_with_custom_name(my_arg):
return "The args is: " + my_arg
#do some magic with each decorated method:
for m in run_this_method.registry:
print(m.__name__)
。像这样:
angular
.module('SaunaDoorCalc', [])
.controller('SaunaDoorCalcController', function($scope, $http) {
$scope.sizeswitch = [
{ label: 'Стандартный', value: 'standard'},
{ label: 'Нестандартный', value: 'special'}
];
$scope.selectedSizeSwitch = $scope.sizeswitch[0].label; // initial value
$scope.standardsizes = [
{ label: '585х1880', price:5600 },
{ label: '685x1880', price:3600 },
{ label: '685x1980', price:5600 },
{ label: '685x2080', price:5600 },
{ label: '685x2180', price:6600 },
{ label: '785x1880', price:5600 },
{ label: '785x1980', price:5600 },
{ label: '785x2080', price:5600 },
{ label: '785x2180', price:6600 }
];
$scope.selectedStandardSize = $scope.standardsizes[1];
.....
if ($scope.selectedSizeSwitch == $scope.sizeswitch[0].label) {
$scope.doorsize = $scope.selectedSizeSwitch + ', ' + $scope.selectedStandardSize.label;
} else {
$scope.doorsize = $scope.selectedSizeSwitch + ', ' + $scope.DoorSizeB + 'x' + $scope.DoorSizeH;
}
$scope.submit = function(isValid) {
if (isValid) {
$http.post($scope.url,
{
"calcname": "saunadoor",
"doorsize": $scope.doorsize,
....... // other variables from my form
}).
success(function(data, status) {
console.log(data);
$scope.status = status;
$scope.data = data;
$scope.result = data;
});
$scope.name = null;
$scope.tel = null;
$scope.email = null;
$scope.msg = null;
$scope.DoorSizeB = null;
$scope.DoorSizeH = null;
$scope.calculator.$setPristine();
$scope.message = 'Заказ отправлен. В ближайшее время мы с вами свяжемся.';
}else{
$scope.message = 'Заполните обязательные поля формы!';
}
}
});
答案 1 :(得分:1)
如果我理解你的问题(如何装饰一个名字未知的方法?)那么这完全有可能。
@decorator
def foo(bar):
pass
是
的合成糖def foo(bar):
pass
foo = decorator(foo)
所以在你的情况下你应该这样做:
method_with_custom_name = run_this_method(method_with_custom_name)
但是,您提供的示例令人困惑。你为什么不知道method_with_custom_name的名字?它就在那里。它被称为method_with_custom_name。要稍后使用装饰版本,只需调用method_with_custom_name。