你的「行動水平」太複雜了。只要你有權訪問它,就處理這些東西。
由於
if not isinstance(parameter_name, str):
raise Exception("parameter_name must be a string")
if not type_converter_fn:
type_converter_fn = the_type
與 「外」 的參數只涉及,你應該做它。
這同樣適用於
arg_position = list(fn.func_code.co_varnames).index(parameter_name) - 1
的更深一層。
一般情況下,我會做(未經測試!):
def ensure_type(parameter_name, the_type, type_converter_fn=None):
if not isinstance(parameter_name, str):
raise Exception("parameter_name must be a string")
if not type_converter_fn:
type_converter_fn = the_type
def decorator(fn):
arg_position = list(fn.func_code.co_varnames).index(parameter_name) - 1 #minus once because of self
def wrapped(self, *args, **kwargs):
if arg_position > -1:
the_arg = args[arg_position]
if the_arg is not None and not isinstance(the_arg, the_type):
all_the_args = list(args)
all_the_args[arg_position] = type_converter_fn(the_arg)
args = tuple(all_the_args)
return fn(self, *args, **kwargs)
return wrapped
return decorator
編輯:正如我剛纔看到:它仍然是太複雜了。
只有在需要時才能進行包裝。 if arg_position < 0
,你可以提出異常(因爲整個東西是毫無意義的,所以使用.find()
而不是.index()
),或者你可以返回原始fn
。
def ensure_type(parameter_name, the_type, type_converter_fn=None):
if not isinstance(parameter_name, str):
raise Exception("parameter_name must be a string")
if not type_converter_fn:
type_converter_fn = the_type
def decorator(fn):
arg_position = list(fn.func_code.co_varnames).index(parameter_name) - 1 #minus once because of self
# Either use .find() here, or live with -1 and return the original function then:
if arg_position < 0: # only needed with .index()
return fn
def wrapped(self, *args, **kwargs):
the_arg = args[arg_position]
if the_arg is not None and not isinstance(the_arg, the_type):
all_the_args = list(args)
all_the_args[arg_position] = type_converter_fn(the_arg)
args = tuple(all_the_args)
return fn(self, *args, **kwargs)
return wrapped
return decorator
請修復您的縮進。至少最後三行是關閉的。 – 2011-12-15 10:46:53