如何在同一个类的前一个实例上调用实例?

时间:2016-04-11 00:05:17

标签: python inheritance instance

如果这个问题有明显的解决方案,或者它是重复的,我会提前道歉。

我有一个课程如下:

class Kernel(object):
    """ creates kernels with the necessary input data """
    def __init__(self, Amplitude, random = None):
        self.Amplitude = Amplitude
        self.random = random
        if random != None:
            self.dims = list(random.shape)

    def Gaussian(self, X, Y, sigmaX, sigmaY, muX=0.0, muY=0.0):
        """ return a 2 dimensional Gaussian kernel """
        kernel = np.zeros([X, Y])
        theta = [self.Amplitude, muX, muY, sigmaX, sigmaY]
        for i in range(X):
            for j in range(Y):
                kernel[i][j] = integrate.dblquad(lambda x, y: G2(x + float(i) - (X-1.0)/2.0, \
                                                 y + float(j) - (Y-1.0)/2.0, theta), \
                                                 -0.5, 0.5, lambda y: -0.5, lambda y: 0.5)[0]
        return kernel

它基本上创建了一堆卷积内核(我只包括第一个)。

我想在这个类中添加一个实例(方法?),以便我可以使用类似

的东西
conv = Kernel(1.5)
conv.Gaussian(9, 9, 2, 2).kershow()

并使用Matplotlib弹出数组。我知道如何编写这个实例并用Matplotlib绘制它,但我不知道如何编写这个类,所以对于每个方法我都希望有这个额外的能力(即.kershow()),我可能以这种方式称呼它。

我可以使用装饰器吗?但我以前从未使用过它们。我怎么能这样做?

2 个答案:

答案 0 :(得分:0)

我将如何做到这一点:

class Kernel(object):

    def __init__ ...

    def Gaussian(...):
        self.kernel = ...
        ...
        return self  # not kernel

    def kershow(self):
        do_stuff_with(self.kernel)

基本上Gaussian方法不返回numpy数组,它只是将它存储在Kernel对象中,以便在类的其他地方使用。特别是kershow现在可以使用它。 return self是可选的,但允许您编写的所需界面

conv.Gaussian(9, 9, 2, 2).kershow()

而不是

conv.Gaussian(9, 9, 2, 2)
conv.kershow()

答案 1 :(得分:0)

您正在寻找的东西的名称是功能或method chaining

字符串是Python中非常好的例子。因为字符串是不可变的,所以每个字符串方法都返回一个新字符串。因此,您可以在返回值上调用字符串方法,而不是存储中间值。例如:

lower = '       THIS IS MY NAME: WAYNE      '.lower()
without_left_padding = lower.lstrip()
without_right_padding = without_left_padding.rstrip()
title_cased = without_right_padding.title()

相反,你可以写:

title_cased = '       THIS IS MY NAME: WAYNE      '.lower().lstrip().rstrip().title()

当然你真的只做.strip().title(),但这只是一个例子。

因此,如果您需要.kernshow()选项,那么您需要在返回的任何内容中包含该方法。在你的情况下,numpy数组没有.kernshow方法,所以你需要返回一些东西。

您的选择主要是:

  • numpy数组的子类
  • 包装numpy数组的类

我不确定子类化numpy数组涉及什么,所以我将坚持使用后者作为例子。您可以使用内核类,也可以创建第二个类。

Alex提供了一个使用内核类的示例,但也可以使用另一个类:

class KernelPlotter(object):
    def __init__(self, kernel):
        self.kernel = kernel

    def kernshow(self):
        # do the plotting here

然后你几乎会关注现有的代码,而不是return kernel你会return KernelPlotter(kernel)

您选择哪个选项实际上取决于对您的特定问题域有何意义。

还有另一个功能链的姐妹称为fluent interface,它基本上是功能链,但其目标是使界面读起来像英语。例如,您可能会有:

Kernel(with_amplitude=1.5).create_gaussian(with_x=9, and_y=9, and_sigma_x=2, and_sigma_y=2).show_plot()

虽然以这种方式编写代码时显然可以some problems