Python装饰器,使OOP代码FP;好主意还是坏主意?

2024-04-26 02:50:18 发布

您现在位置:Python中文网/ 问答频道 /正文

最近,我一直在试图找到一个解决“表达式问题”的方法,在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__方法,但是我可以看到,对于具有多个对比实现的类来说,这会变得非常失控

这是解决问题的公平办法吗?是坏习惯还是坏技巧?我应该单独提供一个还是另一个?你知道吗


Tags: 对象方法key函数selfreturndeffunction
1条回答
网友
1楼 · 发布于 2024-04-26 02:50:18

Python有一个^{}修饰符,用于在不实例化类的情况下使用类方法。只需使用静态方法包装器对类方法进行注释(注意,该方法现在不采用自引用),就可以从类本身调用它。你知道吗

在您的情况下,对于dot产品,只需执行以下操作:

class Vector2D():
    # Magic methods here...

    @staticmethod
    def dot_product(a, b):
        return a[0]*b[1] + a[1]*b[0]

然后,只需调用Vector2D.dot_product(my_vector1, my_vector2)即可使用Vector2D类本身的函数。你知道吗

将类方法分配给全局函数听起来像是一个非常危险、错误、复杂和冗长的解决方案。我会不惜一切代价避免它。你知道吗

相关问题 更多 >