python - 如何将带参数的函数包装到带参数的包装器中?
问题描述
更新V2:好的,我在空闲时间写了一些代码并提出了这个想法。它有效,但我不知道为什么。这些代码之间有什么区别使其真正起作用?
类基础:
def __init__(self):
self.prevention = [
'targetDeceleration',
'collisionPrevention',
]
self.correct = []
self.incorrect = []
def mapping(self, signal: list, data: list or np.ndarray, idx_list: list, filename: str, support: list = None):
def outer_wrapper(func):
def inner_wrapper(*args):
for idx, sig in enumerate(signal):
print(sig)
if support:
print(support[idx])
for idx_triplet in idx_list:
eth_idx, spi_idx, _ = idx_triplet
is_correct = func(sig, eth_idx, spi_idx, support)
if is_correct:
print('Correct')
self.correct.append(sig)
else:
print('Incorrect')
self.incorrect.append(sig)
print(filename)
return inner_wrapper
return outer_wrapper
@abstractmethod
def mapping_check(self):
pass
AEB 类(基础):
def __init__(self):
super().__init__()
def mapping_check(self):
data = np.full((4,), 5)
idx_list = [
[1, 1, 1]
]
fname = 'FILENAME'
@Base.mapping(
self,
signal=self.prevention,
data=data,
idx_list=idx_list,
filename=fname,
support=['idTarget', 'syncId']
)
def prevention_mapping(self, sig: list, eth_idx: int, spi_idx: int) -> bool:
return eth_idx == spi_idx
prevention_mapping()
更新:
@Functionality.mapping_functionality
def id_target_object_fcm_mapping(eth_signal, spi_idx, eth_idx) -> bool:
# FCF_VD_KEYS from A to E
idx_A = FCF_VD_KEYS.index('A')
idx_E = FCF_VD_KEYS.index('E')
fcf_vd_keys = FCF_VD_KEYS[idx_A: idx_E + 1]
# Check ETH and SPI mapping
for key in fcf_vd_keys:
# Check SPI mapping
PDD_469_1_1 = FCF_VD_IDS['FCV'][spi_idx] == FCF_VD_IDS[key][spi_idx]
PDD_469_1_2 = FCF_VD_ALERTS[key][spi_idx] == 43605
PDD_469_1 = PDD_469_1_1 and PDD_469_1_2
if PDD_469_1:
# Check for appropriate idTargetObjectFCMCam values
PDD_469_2 = eth_signal[eth_idx] == FCF_VD_IDS[key][spi_idx]
if PDD_469_2:
return True
# Check for default value
IS_DEFAULT = eth_signal[eth_idx] == 0
if IS_DEFAULT:
return True
# Otherwise return incorrect mapping
return False
def mapping_functionality(self):
def inner_wrapper(function, eth_signal, pickle_data, idx_list, file_name, support_signal=None):
print('inner wrapper')
for idx, sig in enumerate(eth_signal):
# Get ETH signal to be mapped
eth_signal = Functionality.get_eth_signal(sig, pickle_data)
# Load support signal
if support_signal:
support_signal = Functionality.get_eth_signal(support_signal[idx], pickle_data)
for spi_idx, eth_idx, _ in idx_list:
# Boolean storing info whether ETH was mapped correctly to the SPI signal
# Update output
is_mapping_correct = function(eth_signal, spi_idx, eth_idx, support_signal)
if is_mapping_correct:
if self.result[sig] != self.incorrect:
self.result[sig] = self.correct
else:
self.result[sig] = self.incorrect
if sig not in self.corrupted_files[file_name]:
self.corrupted_files[file_name][sig] = []
self.corrupted_files[file_name][sig].append([spi_idx, eth_idx])
return inner_wrapper
不幸的是,在尝试运行代码后:
id_target_object_fcm_mapping(self.id_target_object_fcm_sig, pickle_data, idx_list, file_name)
我收到错误,mapping_functionality() 错过了 file_name 参数。我该如何解决?
所以基本上我想包装这个功能:
@Functionality.mapping_functionality(
self=self,
eth_signal=self.id_target_object_fcm_sig,
pickle_data=pickle_data,
idx_list=idx_list,
file_name=file_name,
)
def id_target_object_fcm_mapping(eth_signal, spi_idx, eth_idx, *args) -> bool:
# FCF_VD_KEYS from A to E
idx_A = FCF_VD_KEYS.index('A')
idx_E = FCF_VD_KEYS.index('E')
fcf_vd_keys = FCF_VD_KEYS[idx_A: idx_E + 1]
# Check ETH and SPI mapping
for key in fcf_vd_keys:
# Check SPI mapping
PDD_469_1_1 = FCF_VD_IDS['FCV'][spi_idx] == FCF_VD_IDS[key][spi_idx]
PDD_469_1_2 = FCF_VD_ALERTS[key][spi_idx] == 43605
PDD_469_1 = PDD_469_1_1 and PDD_469_1_2
if PDD_469_1:
# Check for appropriate idTargetObjectFCMCam values
PDD_469_2 = eth_signal[eth_idx] == FCF_VD_IDS[key][spi_idx]
if PDD_469_2:
return True
# Check for default value
IS_DEFAULT = eth_signal[eth_idx] == 0
if IS_DEFAULT:
return True
# Otherwise return incorrect mapping
return False
进入一个将遍历索引并根据包装函数的布尔值更新电子表格的函数:
def mapping_functionality(self, eth_signal, pickle_data, idx_list, file_name, support_signal=None):
for idx, sig in enumerate(eth_signal):
# Get ETH signal to be mapped
eth_signal = Functionality.get_eth_signal(sig, pickle_data)
# Load support signal
if support_signal:
support_signal = Functionality.get_eth_signal(support_signal[idx], pickle_data)
def outer_wrapper(function):
# Iterate over signal indices
for spi_idx, eth_idx, _ in idx_list:
# Boolean storing info whether ETH was mapped correctly to the SPI signal
@wraps(function)
def inner_wrapper():
is_mapping_correct = function(eth_signal, spi_idx, eth_idx, support_signal)
# Update output
if is_mapping_correct:
if self.result[sig] != self.incorrect:
self.result[sig] = self.correct
else:
self.result[sig] = self.incorrect
if sig not in self.corrupted_files[file_name]:
self.corrupted_files[file_name][sig] = []
self.corrupted_files[file_name][sig].append([spi_idx, eth_idx])
return inner_wrapper
return outer_wrapper
不幸的是,在尝试调用该函数后:
id_target_object_fcm_mapping()
我收到以下错误:
TypeError: 'NoneType' object is not callable
我该如何解决这个问题?
解决方案
由于您没有提供有关类对象以及您正在尝试做什么的信息,因此很难理解您的代码行为是否与修复预期的一样。
通常,最好简化问题并将其作为 SO 上的可重现示例提供。
假设您的潜在问题是标题所暗示的,
如何将带参数的函数包装到带参数的包装器中?
这是通过装饰器传递参数的一般结构如下。希望这可以帮助 -
def decorator_function(n):
def outer_wrapper(f):
def inner_wrapper(*args, **kwargs):
out = f(*args, **kwargs)**n
return out
return inner_wrapper
return outer_wrapper
@decorator_function(4) #<- Decorator with argument
def function(x, m):
return x/m
print(function(10,3))
print((10/3)**4)
123.45679012345681
123.45679012345681
原始函数x
将其除以m
。包装器接受n
并将其作为原始函数输出的幂,因此,(x/m)^n
编辑:只是添加创建嵌套装饰器函数的 lambda 函数方法,因为我个人觉得它们更具可读性(很奇怪吧?)
decorator = lambda n:lambda f:lambda *args, **kwargs: f(*args, **kwargs)**n
@decorator(4)
def function(x, m):
return x/m
function(10,3)
123.45679012345681
你可以很容易地看到这里发生了什么 -
lambda n:lambda f:lambda *args, **kwargs: f(*args, **kwargs)**n
# | | |________________| | |
# | | original function | |
# | |___________________________________________| |
# | wrapper takes in f and returns inner lambda |
# |_______________________________________________________________|
# outer function takes n parameter and returns wrapper
推荐阅读
- excel - 在活动单元格下的表格中添加一行
- c# - 使用附加属性从 View 更新 ViewModel
- python - python - 如何检查df中所有列的dtypes在python中是否相同?
- sql - 在 ClickHouse 中将列数据透视到 NxM 表中
- netsuite - 我们如何从记录顶部删除/更改销售订单状态的标签?
- webrtc - 从源头构建 Jitsi 的令人费解的斗争
- go - 编写具有多个可选参数的 API 端点
- python - 在 Django 模板中的对象内加载对象
- azure-data-factory - 获取文件中查找活动的输出
- javascript - 响应式菜单的 JS 和 Bootstrap?