如果这个问题有明显的解决方案,或者它是重复的,我会提前道歉。
我有一个课程如下:
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()
),我可能以这种方式称呼它。
我想我可以使用装饰器吗?但我以前从未使用过它们。我怎么能这样做?
答案 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数组涉及什么,所以我将坚持使用后者作为例子。您可以使用内核类,也可以创建第二个类。
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。