Python 使用类而不是全局变量

Python 使用类而不是全局变量,python,class,global-variables,Python,Class,Global Variables,我有一个程序可以对一个数组进行一些操作(小波变换和各种其他复杂性),然后将它与前一个数组及其属性进行比较,输出一个比较两者的图形,最后更新“前一个”数组以包含此信息。 基本上,我的程序开始变得有点长,很难阅读,但我不能真正将它分解成函数,因为所有函数都在读取和更改相同的变量。没有定义所有这些变量为全局变量,每次我想要一个函数改变它们,这是相当困难的 然后我在网上找到了这个: 您可能有几个使用相同状态变量的函数,可以读取或写入它们。您正在传递许多参数。您有嵌套函数,这些函数必须将其参数转发给它们使

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

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

您可能有几个使用相同状态变量的函数,可以读取或写入它们。您正在传递许多参数。您有嵌套函数,这些函数必须将其参数转发给它们使用的函数。您试图使用一些模块变量来保存状态

你可以改成上课!一个类的所有方法都可以访问该类的所有距离数据。通过将共享状态存储在类中,可以避免将其作为参数传递给方法

所以我想知道我该如何调整我的程序,使其改为使用类来编写? 我可以附上我的代码,如果它有帮助,但它相当长,我不想填补论坛

代码如下:

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
导入操作系统、系统、字符串、数学
从optpasse导入OptionParser
将numpy作为np导入
导入pywt
将matplotlib.pyplot作为plt导入
将matplotlib.mlab导入为mlab
从matplotlib.ticker导入MaxNLocator
导入glob
dir=os.getcwd()
profiles=glob.glob(dir+“/B0740-28/*_edit.FT.ascii”)
对于范围内的x(0,透镜(轮廓)):
配置文件[x]=配置文件[x][28:]
#生成配置文件名列表
模式='每'
小波=['db12']
级别=范围(3,4)
开始=[]
图=1
ix=0#剖面索引
变化=np.零(透镜(轮廓))
#用于记录形状更改的数组
对于级别中的num_级别:
对于小波中的小波:
对于配置文件中的配置文件:
prof_name=profile.partition('.')[0]
#删除文件扩展名
pfile=打开(dir+'/B0740-28/'+配置文件)
数据=[]
对于pfile中的行:
数据追加(浮动(行))
data=np.array(数据)
end=len(数据)
数据=np.数组(数据)/最大值(数据)
#获取脉冲波形并进行归一化
#忽略前两行
wav_name=wavelet.partition('.')[0]
w=pywt.小波(小波)
有用=pywt.dwt_最大_级别(结束,w)
#找到分解的最大级别
系数=pywt.wavedec(数据、小波、模式、级别=数量级)
#创建小波系数:cAn、cDn、cD(n-1)。。。cD1
低通=pywt.upcoef('a',系数[0],小波,电平=num_电平,take=end)
高通=np.零(结束)
对于范围(1)(num_levels+1))内的x:
高通+=pywt.upcoef('d',coefs[len(coefs)-x],小波\
标高=x,取数=终点)
#upcoef逆变换
#定义高通和低通组件
对于范围(0,len(数据))中的n:
如果浮动(数据[n])>0.4:
值=n
开始。追加(值)
打破
如果配置文件!=配置文件[0]:
偏移量=开始[0]-值
数据=np.滚动(数据,偏移)
低通=np.滚动(低通,偏移)
高通=np滚动(高通,偏移)
#调整轮廓,使其对齐
如果profile==profiles[0]:
数据_prev=0
低通_prev=0
高通_prev=0
mxm=data.argmax()
低压差=低通-低通
diff_high=高通-高通前

如果max(diff_low)>=0.15或min(diff_low)这样的值就是您想要的:

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()

我可能会对这个答案投反对票,但从总体来看,在这种特殊情况下,我并不认为向包中添加一些全局变量有什么问题


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

“使用数组进行操作…,然后将其与以前的数组及其属性进行比较”-听起来像是拥有一个类的两个实例的主要候选者谢谢:)那么,我有没有办法从程序一开始就将某些变量定义为全局变量,这样它们就可以被所有不同的函数看到和编辑?我想你指的是“模块”而不是包(在Python中是不同的东西)。前者是内置类
module
的实例,其中定义的东西是实例属性-所以你说的就是使用一个类…你也可以发布你的代码-如果太长,它会被放在一个滚动框中,我会先创建包含大量参数的函数,然后计算出哪些代码位需要哪些变量。谢谢!这很有帮助!我的变量比数据数组多得多,可能有10个左右,我循环了47/48个不同的情况(从一个文件中读取每个数组),所以我不能真的做m=,n=等等。目前我从一个文件中读取所有数组,然后循环它们。@HelenJohnson:这些变量中有多少是全局的?它们中的一些可以只用于一个功能吗?无论如何,您可以向构造函数中添加更多参数。使用类并不能真正消除全局变量,因为它们的实例(例如答案中的
m
n
)仍然是全局变量。使用它们仍然是一个很好的实践