最好的pythonic练习,以避免重复代码?

时间:2016-04-14 14:48:04

标签: python matplotlib

我不确定是否有人问这个问题 - 到目前为止还找不到好的做法。

我有两个python文件,包含完全相同的包导入,以及许多不同的方法。有几个变量只有变化,而其他变量则相同。

如果我需要对一个文件进行更改,我必须转到另一个文件来应用相同的更改,而这些更改似乎并不是一种强大的方式。

我真的想将这些文件分开(在两个文件中)。我从来没有很好地理解class的想法。我是否需要在第一个文件中创建class所有方法,循环,变量,并在第二个文件中调用它,然后我可以覆盖变量(如果需要)?

这是我的第一个文件的样子,道歉我应该花一些时间让它可读,但它只是为了让你了解结构。这段代码实际上绘制了一些matplotlib数字。第二个文件将有不同的输入文件(CSV文件),然后绘制不同的数字。

import csv
import datetime
import pylab
import sys
import time
from inspect import getsourcefile
from os.path import abspath

import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import style
from matplotlib.backends.backend_pdf import PdfPages


def get_mul_list(*args):
    return map(list, zip(*args))


def str2float(s):
    if not s == '':
        s = (float(s))
    else:
        s = np.nan
    return s


def clean_nans(x, y, num_nan_gap=24):
    x_clean, y_clean = [], []
    cnt = 0
    for _x, _y in zip(x, y):
        if np.isnan(_y):
            cnt += 1
            if cnt == num_nan_gap:
                 # on the 5th nan, put it in the list to break line
                 x_clean.append(_x)
                 y_clean.append(_y)
            continue
        cnt = 0
        x_clean.append(_x)
        y_clean.append(_y)
    return x_clean, y_clean


def csv_store_in_dict(filepath, mode):
    csv_data = open(filepath, mode)
    data = list(csv.reader(csv_data))
    csv_imported_in_dict = dict(zip(data[0], get_mul_list(*data[1:])))
    return csv_imported_in_dict

colors_list = ['deeppink', 'aquamarine', 'yellowgreen', 'orangered', 'darkviolet',
          'darkolivegreen', 'lightskyblue', 'teal', 'seagreen', 'olivedrab', 'red', 'indigo', 'goldenrod', 'firebrick',
          'slategray', 'cornflowerblue', 'darksalmon', 'blue', 'khaki', 'wheat', 'dodgerblue', 'moccasin', 'sienna',
          'darkcyan']

current_py_filepath = abspath(getsourcefile(lambda: 0))  # python source file path for figure footnote

kkk_dict = csv_store_in_dict('CSV/qry_WatLvl_kkk_xlsTS_1c_v4.csv', 'r')  # all WL kkk data stored in a dictionary
yyyddd_dict = csv_store_in_dict('CSV/qry_WatLvl_TimeSeries2_v2.csv', 'r')  # all WL kkk data stored in a dictionary
XX_info_dict = csv_store_in_dict('CSV/XX_info.csv', 'r')  # XX_name, XX_group_name, BB_Main, CC, dddd

XX_groups_chartE = ('XXH_05',
                    'XXH_16',
                    'XXH_11',
                    'DXX_27',
                    'DXX_22',
                    'DXX_21',
                    'DXX_09',
                    'DXX_07',
                    'DXX_01',
                    'DXX_05',)

y_range = [[5,10],  # chart 1
           [7,12],  # chart 2
           [3,8],  # chart 3
           [7,12],  # chart 4
           [5,10],  # chart 5
           [20,50],  # chart 6
           [12,22],  # chart 7
           [5,25],  # chart 8
           [10,15],  # chart 9
           [22,42]]  # chart 10

# Date conversion
x_kkk_date = []
x_yyy_date = []
x_kkk = kkk_dict["DateTime"]
x_yyyddd = yyyddd_dict["DateTime"]
for i in x_kkk:
    x_kkk_date.append(datetime.datetime.strptime(i, "%d/%m/%Y %H:%M:%S"))
for i in x_yyyddd:
    x_yyy_date.append(datetime.datetime.strptime(i, "%d/%m/%Y %H:%M:%S"))

# plotting XX groups
XXs_curr_grp = []
chart_num = 1  
for XX_gr_nam in XX_groups_chartE:
    for count, elem in enumerate(XX_info_dict['XX_group_name']):
        if elem == XX_gr_nam:
            XXs_curr_grp.append(XX_info_dict['XX_name'][count]) 

    fig = plt.figure(figsize=(14, 11))  

    col_ind = 0

    for XX_v in XXs_curr_grp:  
        y_kkk = kkk_dict[XX_v] 
        y_yyyddd = yyyddd_dict[XX_v] 

        y_kkk_num = [str2float(i) for i in y_kkk] 
        y_yyyddd_num = [str2float(i) for i in y_yyyddd] 

        ind_XX = XX_info_dict["XX_name"].index(XX_v)  
        BB_Main = XX_info_dict["BB_Main"][ind_XX]  
        CC = XX_info_dict["CC"][ind_XX]  
        dddd = XX_info_dict["dddd"][ind_XX]  

        def label_pl(d_type):
            label_dis = "%s (%s, %s / %s)" % (XX_v, BB_Main, CC, d_type)
            return label_dis

        x_kkk_date_nan_cln, y_kkk_num_nan_cln = clean_nans(x_kkk_date, y_kkk_num, 200)

        plt.plot_date(x_kkk_date_nan_cln, y_kkk_num_nan_cln, '-', markeredgewidth=0,
                      label=label_pl("kkk data"), color=colors_list[col_ind])  # c = col_rand

        plt.scatter(x_yyy_date, y_yyyddd_num, label=label_pl("yyy ddds"), marker='x', linewidths=2,
                    s=50, color=colors_list[col_ind])
        col_ind += 1


    XX_grp_title = XX_gr_nam.replace("_", "-")
    plt.title("kkk Levels  \n" + XX_grp_title + " Group", fontsize=20)
    plt.ylabel('wwL (mmm)')
    plt.legend(loc=9, ncol=2, prop={'size': 8})
    plt.figtext(0.05, 0.05, current_py_filepath, horizontalalignment='left', fontsize=8)  # footnote for file path
    plt.figtext(0.95, 0.05, 'Chart E%s' % (chart_num,), horizontalalignment='right', fontsize=12)  # chart number
    plt.figtext(0.95, 0.95, datetime.date.today(), horizontalalignment='right', fontsize=8)


    # FIGURE FORMATTING
    myFmt = mdates.DateFormatter('%d/%m/%Y')
    ax = plt.gca()
    ax.xaxis.set_major_formatter(myFmt)
    plt.gcf().autofmt_xdate()
    ax.set_ylim(y_range[chart_num-1])
    plt.grid()
    fig.tight_layout() 
    plt.subplots_adjust(left=0.05, right=0.95, top=0.9, bottom=0.15)
    fig_pdf_file = "PDF/OXX_grp_page %s.pdf" % (chart_num,)
    fig.savefig(fig_pdf_file)
    XXs_curr_grp = []
    chart_num += 1  # assumed charts numbering is the same as the order of plotting
plt.show()

1 个答案:

答案 0 :(得分:2)

不,您不需要定义类。您需要从一个文件中删除共享功能,并将其导入另一个文件。 import语句可以导入已安装的python包,也可以导入python文件。像这样使用它:

# myfile.py

def f(x):
    return x * 2

# main.py

import myfile

myfile.f(2)

请注意,对于此示例,两个文件必须位于同一目录中。

但是,如果您想将myfile.py存储在不同的目录中,即在此层次结构中:

my_project
----main.py
----my_modules
        ----myfile.py
        ----__init__.py

只需在“my_modules”目录中创建一个空的__init__.py文件,然后更改您的import语句以反映import my_modules.myfile