python - 使用类而不是全局变量

标签 python class global-variables

我有一个程序可以对一个数组进行一些操作(小波变换和其他各种复杂的操作),然后将它与前一个数组及其属性进行比较,输出一个比较两者的图形,最后将“前一个”数组更新为包含此信息。 基本上我的程序开始变得有点长而且难以阅读,但我不能真正将它拆分成函数,因为所有函数都在读取和更改相同的变量。每次我想要一个函数来改变它们时,如果不将所有这些变量都定义为全局变量,这非常困难。

然后我在网上找到了这个:

You may have several functions that use the same state variables, either reading or writing them. You are passing a lot of parameters around. You have nested functions that have to forward their parameters to the functions they use. You are tempted to make some module variables to hold the state.

You could make a class instead! All methods of a class have access to all istance data of the class. By storing the shared state in the class, you avoid the need to pass it as parameters to the methods.

所以我想知道如何调整我的程序以改用类来编写? 如果有帮助,我可以附上我的代码,但它很长,我不想填满论坛!

代码如下:

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,'Lowpass\nChange')
            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

最佳答案

我可能会因为这个答案而被否决,但在宏伟的计划中,在这种特殊情况下,我并没有真正看到向您的包中添加一些全局变量的问题。

当您有一堆功能要在许多不同的地方使用时,类非常有用,但是,您所描述的内容听起来非常具体并且不太可能在其他地方重用。使用实例变量创建一次性类与在包中使用全局变量创建一堆函数并没有太大区别。

关于python - 使用类而不是全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13823254/

相关文章:

python - MySQLdb Like 带有通配符的运算符

c++ - 如果我在不同的类中包含一个基类,该基类的派生类是否也包含在内

c++ - 使用 const 数组的元素在类中定义数组大小时,“数组边界不是整数常量”

python - 全局变量未更新(Processing.py)

javascript - 具有 ID 的 DOM 树元素是否成为全局属性?

python - Django:每个 "event__pk"的聚合

python - 如何以简单的方式使 matplotlib 标记对色盲友好?

python - 迭代 pandas Series 仅执行一次

Python 实例和类命名空间

c - 从全局结构中读取时是否需要信号量?