仅查看这两行中的前两行。
if not check_abs(_abs_dir):
return False
这些是函数(只需查看参数和前两行,函数的内容与此问题无关)。
def check_is_file(_abs_dir:str):
if not check_abs(_abs_dir):
return False
return os.path.isfile(
norm_case_norm_path(_abs_dir)
)
def create_file_or_folder(_name:str, _abs_dir:str, _is_file:bool):
if not check_abs(_abs_dir):
return False
abs_dir = join(_abs_dir, _name)
create = False
if check_existence(abs_dir):
if _is_file and not check_is_file(_abs_dir):
create = True
if not _is_file and not check_is_folder(_abs_dir):
create = True
else:
create = True
if create:
if _is_file:
open(abs_dir, "a").close()
elif not _is_file:
os.makedirs(abs_dir)
return create
return create
如何制作这些代码
if not check_abs(_abs_dir):
return False
进入check_is_file()
和create_file_or_folder()
的装饰器?两种功能都有不同的参数和位置。
答案 0 :(得分:0)
问题是你不知道要检查哪个参数,因为它在你要装饰的每个函数中的不同位置。但是,您可以使用inspect
模块检查每个函数的签名,检查以确保它具有指定名称的参数,如果是,则将形式参数名称映射到实际参数值每次调用它时都会传递给函数。
拥有该信息可以确定与目标参数关联的参数的值并根据需要对其进行处理 - 在您的代码和下面的示例中,将调用check_abs()
函数的值为传递的_abs_dir
参数并检查函数的返回值。
(注意:已修改为支持多个命名参数。)
from functools import wraps
import inspect
def check_abs(_abs_dir):
print('check_abs({!r}) called'.format(_abs_dir))
return True
def check_abs_param(*params):
def decorator(function):
sig = inspect.signature(function)
if any(map(lambda param: param not in sig.parameters, params)):
raise NameError('One or more expected parameter names missing from '
'declaration "{}{}:".'.format(function.__name__, sig))
@wraps(function)
def wrapped(*args, **kwargs):
bound = sig.bind(*args, **kwargs) # Map parameter names to argument values.
for param in params:
arg_value = bound.arguments[param] # Get argument value.
if not check_abs(arg_value):
return False if sig.return_annotation == bool else None
return function(*args, **kwargs)
return wrapped
return decorator
# tests
try:
@check_abs_param('_abs_dir')
def check_is_bogus(somearg): # param name does not match decorator
print('check_is_bogus() called\n')
except NameError as exc:
print(exc)
print('NameError exception raised from "check_is_bogus(somearg):" declaration, as '
'expected.\n')
else:
print('Error: Expected exception NOT raised from "check_is_bogus(somearg):" '
'declaration.\n')
@check_abs_param('_abs_dir')
def check_is_file(_abs_dir:str):
print('check_is_file() called\n')
@check_abs_param('_abs_dir')
def create_file_or_folder(_name:str, _abs_dir:str, _is_file:bool):
print('create_file_or_folder() called\n')
@check_abs_param('source_dir_abs', 'dest_dir_abs')
def copy_file_or_folder(source_dir_abs:str, dest_dir_abs:str) -> bool:
print('copy_file_or_folder() called\n')
#check_is_bogus('first_dir') # can't call, definition failed
check_is_file('second_dir')
create_file_or_folder('name', 'third_dir', 'False')
copy_file_or_folder('source_dir', 'dest_dir')
输出:
One or more expected parameter names missing from declaration "check_is_bogus(somearg):".
NameError exception raised from "check_is_bogus(somearg):" declaration, as expected.
check_abs('second_dir') called
check_is_file() called
check_abs('third_dir') called
create_file_or_folder() called
check_abs('source_dir') called
check_abs('dest_dir') called
copy_file_or_folder() called