【发布时间】:2021-09-25 14:00:09
【问题描述】:
请考虑以下代码:
def build_matrix(x_coordinates, y_coordinates, calc_element, **kwargs):
matrix = np.zeros((len(x_coordinates), len(y_coordinates)))
for i in range(len(x_coordinates)):
for j in range(len(y_coordinates)):
matrix += calc_element(x_coordinates[i], y_coordinates[j], i, j, **kwargs)
return matrix
函数build_matrix 用于通过使用名为calc_element 的函数填充其元素来构建矩阵。由于我不确切知道可能传递给此 build_matrix 函数的所有可能函数是什么,因此我使用可选的关键字参数,这样我就不需要在每次使用它时都更改 build_matrix另一个函数(所有这些函数唯一的共同点是它们需要参数x_coords_i, y_coords_j, i, j)
但是,我想知道在这种情况下使用类而不是函数是否符合 Pythonic。例如,如果我要通过以下方式定义特定版本的calc_element
class calc_element_velocity_mass():
def __init__(self, velocity, mass):
self.velocity = velocity
self.mass = mass
def __call__(self, x_coords_i, y_coords_j, i, j):
return self.velocity * i / x_coords_i - y_coords_j * j * self.mass
然后如下初始化后
calc_element = calc_element_velocity_mass(20, 10)
我可以在不使用可选关键字参数的情况下将其传递给build_matrix,例如,无需将kwargs = dict(mass = 10, velocity = 20) 传递给build_matrix。
问题:这是一种正确的上课方式吗?我的原始实现是否正确,或者我应该以不同的方式处理这个问题?谢谢!
【问题讨论】:
-
任何一个选项对我来说都是合理的。这里的主要内容是
build_matrix()定义了calc_element的使用方式。如果您正在设计build_matrix,那么您在决定合同应该是什么方面有很大的灵活性。请注意,当前实现允许build_matrix()取空kwargs,因此calc_element_velocity_mass类将按原样使用它。 -
嗯,对于初学者来说,
def __init__(self, **kwargs):可能应该只是def __init__(self, velocity, mass)。在任何情况下,任何一个都可以。 -
注意,你的函数的客户端可以只传递
lambda x_cords_i, y_cords_j, i, j: calc_element(x_cords_i, y_cords_j, i, j, velocity=20, mass=10)例如(即使用部分应用程序)。重要的是您的 API 已正确记录
标签: python class keyword-argument optional-arguments