最近,我一直在试图找到一个解决“表达式问题”的方法,在OOP或FP(函数式编程)中实现代码。我用来说明我的问题的例子是Vector2D类。我可以创建一个类,其中包含2D向量的所有必要函数(点积、幅值等),或者创建一组函数,这些函数采用表示向量的2元组。我选择了哪种选择?你知道吗
为了解决这个问题,我认为制作一个接受类的方法并将它们转换为全局函数的装饰器可能会很好。我就是这样做的:
import types
def function(method):
method._function = True
return method
def make_functions(cls):
for key in cls.__dict__:
method = getattr(cls, key)
if not isinstance(method, types.FunctionType):
continue
if hasattr(method, '_function') and method._function:
globals()[method.__name__] = method
return cls
@make_functions
class Vector2D:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return 'Vector(%g, %g)' % (self.x, self.y)
def __iter__(self):
for component in self.x, self.y:
yield component
def __getitem__(self, key):
return (self.x, self.y)[key]
def __setitem__(self, key, val):
if key == 0:
self.x = val
elif key == 1:
self.y = val
else:
print('not cool man')
def __add__(self, other):
x = self[0] + other[0]
y = self[1] + other[1]
return self.__class__(x, y)
__radd__ = __add__
def __sub__(self, other):
x = self[0] - other[0]
y = self[1] - other[1]
return self.__class__(x, y)
def __rsub__(self, other):
x = other[0] - self[0]
y = other[1] - self[1]
return self.__class__(x, y)
def __mul__(self, other):
x = other * self[0]
y = other * self[1]
return self.__class__(x, y)
__rmul__ = __mul__
@function
def dot_product(self, other):
return self[0]*other[1] + self[1]*other[0]
现在,dot_product
不仅是Vector2D
类的一个方法,它还是一个全局函数,接收两个向量(或类似向量的对象)。这既满足了实现这样一个对象的函数方法,也满足了面向对象的方法。我能预见这种方法的唯一问题是,任何可以表示为另一个对象(如元组或列表)的类,必须定义为与行为类似的对象以相同的方式工作。对于一个也可以是元组的向量来说,这并不是很糟糕,因为我们所要做的就是定义__getitem__
和__iter__
方法,但是我可以看到,对于具有多个对比实现的类来说,这会变得非常失控
这是解决问题的公平办法吗?是坏习惯还是坏技巧?我应该单独提供一个还是另一个?你知道吗
Python有一个^{} 修饰符,用于在不实例化类的情况下使用类方法。只需使用静态方法包装器对类方法进行注释(注意,该方法现在不采用自引用),就可以从类本身调用它。你知道吗
在您的情况下,对于dot产品,只需执行以下操作:
然后,只需调用
Vector2D.dot_product(my_vector1, my_vector2)
即可使用Vector2D
类本身的函数。你知道吗将类方法分配给全局函数听起来像是一个非常危险、错误、复杂和冗长的解决方案。我会不惜一切代价避免它。你知道吗
相关问题 更多 >
编程相关推荐