我有一个程序可以对数组进行一些操作(小波变换和各种其他复杂度),然后将其与上一个数组及其属性进行比较,输出一个比较两者的图,最后更新"上一个"数组以包含此信息。基本上,我的程序开始变得有点长,很难阅读,但我不能真正把它分成函数,因为所有的函数都在读取和更改相同的变量。如果不将所有这些变量定义为全局变量,每当我想要一个函数来更改它们时,这是非常困难的。
然后我在网上找到了这个:
您可能有几个函数使用相同的状态变量,可以读取或写入它们。你传递了很多参数。您有嵌套函数,这些函数必须将其参数转发给它们使用的函数。您很想创建一些模块变量来保存状态。
你可以改成上课!类的所有方法都可以访问该类的所有istance数据。通过将共享状态存储在类中,可以避免将其作为参数传递给方法。
所以我想知道如何调整我的程序以使用类编写?如果有帮助的话,我可以附上我的代码,但它很长,我不想填满论坛!
这是代码:
import os, sys, string, math
from optparse import OptionParser
import numpy as np
import pywt
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
from matplotlib.ticker import MaxNLocator
import glob
dir = os.getcwd()
profiles = glob.glob(dir+"/B0740-28/*_edit.FT.ascii")
for x in range(0,len(profiles)):
profiles[x] = profiles[x][28:]
#produce list of profile file names
mode = 'per'
wavelets = ['db12']
levels = range(3,4)
starts = []
fig = 1
ix = 0 #profile index
changes = np.zeros(len(profiles))
#array to record shape changes
for num_levels in levels:
for wavelet in wavelets:
for profile in profiles:
prof_name = profile.partition('.')[0]
#remove file extension
pfile=open(dir+'/B0740-28/'+profile)
data = []
for line in pfile:
data.append(float(line))
data = np.array(data)
end = len(data)
data = np.array(data)/max(data)
#get pulse profile and normalise
#ignore first 2 lines
wav_name = wavelet.partition('.')[0]
w = pywt.Wavelet(wavelet)
useful = pywt.dwt_max_level(end,w)
#find max level of decomposition
coeffs = pywt.wavedec(data,wavelet,mode,level=num_levels)
#create wavelet coefficients: cAn, cDn, cD(n-1)... cD1
lowpass = pywt.upcoef('a',coeffs[0],wavelet,level=num_levels,take=end)
highpass = np.zeros(end)
for x in range(1,(num_levels+1)):
highpass += pywt.upcoef('d',coeffs[len(coeffs)-x],wavelet,
level=x,take=end)
#reverse transform by upcoef
#define highpass and lowpass components
for n in range(0,len(data)):
if float(data[n]) > 0.4:
value = n
starts.append(value)
break
if profile != profiles[0]:
offset = starts[0]- value
data = np.roll(data,offset)
lowpass = np.roll(lowpass,offset)
highpass = np.roll(highpass,offset)
#adjust profiles so that they line up
if profile == profiles[0]:
data_prev = 0
lowpass_prev = 0
highpass_prev = 0
mxm = data.argmax()
diff_low = lowpass - lowpass_prev
diff_high = highpass - highpass_prev
if max(diff_low) >= 0.15 or min(diff_low) <= -0.15:
changes[ix] = 1
else: changes[ix] = 0
#significant change?
def doPlotting(name,yaxis):
plt.plot(name)
plt.xlim([mxm-80,mxm+100])
plt.ylabel(yaxis)
plt.gca().yaxis.set_major_locator(MaxNLocator(nbins=4))
figure = plt.figure(fig)
figure.subplots_adjust(hspace =.5)
plt.suptitle('Comparison of Consecutive Profiles')
plt.subplot(411); plt.plot(data_prev);
doPlotting(data,'Data'); plt.ylim(ymax=1.1)
plt.subplot(412); plt.plot(lowpass_prev);
doPlotting(lowpass,'Lowpass'); plt.ylim(ymax=1.1)
plt.subplot(413); plt.plot(highpass_prev); doPlotting(highpass,'Highpass')
plt.subplot(414); doPlotting(diff_low,'LowpassnChange')
plotname = 'differences_'+str(ix+1)+'_'+wav_name+'_'+str(num_levels)
plt.savefig(dir+'/B0740-28/Plots/'+plotname)
#creates plots of two most recent profiles + their decomposition
fig += 1
ix += 1
#clears the figure content
#increase array index
data_prev = data
lowpass_prev = lowpass
highpass_prev = highpass
#reassigns 'previous profile' values
figure = plt.figure(fig)
plt.plot(changes)
plt.title('Lowpass Changes')
plt.xlabel('Profile Number')
plt.ylabel('Change > Threshold?')
plt.ylim(-0.25,1.25)
plt.xlim(0,48)
plt.savefig(dir+'/B0740-28/Plots/changes')
#Save lowpass changes plot
我可能会对这个答案投反对票,但从总体来看,在这种特殊情况下,我并不认为在包中添加一些全局变量有什么问题。
当你有一堆想要在很多不同地方使用的功能时,类是非常棒和有用的,然而,你所描述的听起来非常具体,不太可能在其他地方重复使用。创建一个带有实例变量的一次性类与在一个带有全局变量的包中拥有一堆函数并没有太大区别。
你想要这样的东西:
class MyDataProcessor(object):
def __init__(self, data_array):
self.data_array = data_array
def processX(self):
# do stuff with self.data_array
def processY(self):
# do stuff with self.data_array
m = MyDataProcessor([1, 2, 3, 4, 5])
m.processX()
n = MyDataProcessor([5, 4, 3, 2, 1])
n.processX()