关于python:使用用作class-attribute的函数的微妙意外行为

Subtle unexpected behaviour with a function used as class-attribute

我有一段代码,当我更改了一个属性并使其成为类属性时,它被破坏了,我想知道为什么。

所以,我从

1
2
3
4
5
6
7
8
9
10
def linInterp(x1, x2, y1, y2, x):
    return y1 + (x - x1) * (y2 - y1) / (x2 - x1)

class Inter1DLineal(object):
    def __init__(self):
        self.interpSegment = linInterp

if __name__ =="__main__":
    inter = Inter1DLineal()
    print(inter.interpSegment(0.2, 0.6, 0, 1, 0.4))

很好用。我知道我可以在Inter1DLineal中实现interpSegment作为适当的方法,例如

1
2
3
@classmethod
def interpSegment(cls, *args, **kwargs):
    return linInterp(*args, **kwargs)

但我认为我对类型函数的属性很好。

让我吃惊的是接下来发生的事。我决定,因为interpSegment对于所有实例都是通用的,所以我应该将它设置为类属性。

1
2
3
4
5
6
7
8
9
10
11
def linInterp(x1, x2, y1, y2, x):
    return y1 + (x - x1) * (y2 - y1) / (x2 - x1)

class Inter1DLineal(object):
    interpSegment = linInterp
    def __init__(self):
        pass

if __name__ =="__main__":
    inter = Inter1DLineal()
    print(inter.interpSegment(0.2, 0.6, 0, 1, 0.4))

但这打破了密码。似乎对interpSegment的调用正在传递6个属性,而不是5个。有人能解释为什么会这样吗?做这件事最偏执的方式是什么?


好吧,您正在传递inter作为第一个参数,它是self参数。因此,本质上,在"__main__"代码中,您传递的内容如下:

interpSegment(inter, 0.2, 0.6, 0, 1, 0.4)

你应该称之为:

Inter1DLineal.interpSegment(0.2, 0.6, 0, 1, 0.4)

不过,我也要说明,你首先做的事情,在interpSegment__init__的地方,或者作为一种独立的方法,是一种更好的方法。