具有重复代码行的 11 个函数 - 有没有办法减少冗余?

问题描述

我使用的是带有 Arcpy 的 Python 2.7.14(不,我不能使用 Python 3,因为 Arcpy 不支持该版本)。

我有 11 个定义的函数,每个函数都有不同的计算。但是,除了计算之外,每个函数都有相同的代码行。

这里以一个完整的函数为例:

def NYC():
    MTPZ_fields = ['DBH_Calc','MTPZ','MTPZ_Buffer']
    buffer_output = arcpy.GetParameterasText(3)
    buffer_distance = "MTPZ_Buffer"

    # Calculation (different in each function)
    with arcpy.da.UpdateCursor(Tree_Points,Fields) as nyc_cursor:
        for row in nyc_cursor:
            if (row[0]>0 and row[0] <=10):
                row[1] = (1.5*2)+row[0]/100
            elif (row[0]>=10 and row[0] <=25):
                row[1] = (2.4*2)+row[0]/100
            elif (row[0]>25 and row[0] <=37.5):
                row[1] = (3*2)+row[0]/100
            elif (row[0]>37.5 and row[0] <=50):
                row[1] = (3.6*2)+row[0]/100
            elif (row[0]>50 and row[0] <=70):
                row[1] = (4.5*2)+row[0]/100
            nyc_cursor.updateRow(row)

    with arcpy.da.UpdateCursor(points,MTPZ_fields) as mptz_cursor:
        for row in mptz_cursor:
            if (row[1] !=None):
                row[2] = row[1]/2
            mptz_cursor.updateRow(row)

    arcpy.Buffer_analysis(points,buffer_output,buffer_distance)

在我拥有的 11 个函数中,以下几行完全相同:

    MTPZ_fields = ['DBH_Calc','MTPZ_Buffer']
    buffer_output = arcpy.GetParameterasText(3)
    buffer_distance = "MTPZ_Buffer"

还有:

    with arcpy.da.UpdateCursor(points,buffer_distance)

有没有办法减少每个函数中的冗余/重复代码行?

解决方法

你可以试试装饰器。不清楚你想传递什么参数和变量范围,但你可以尝试这样的事情。

def nyc_decorator(func):
    def inner():
        MTPZ_fields = ['DBH_Calc','MTPZ','MTPZ_Buffer']
        buffer_output = arcpy.GetParameterAsText(3)
        buffer_distance = "MTPZ_Buffer"
        func()
        with arcpy.da.UpdateCursor(points,MTPZ_fields) as mptz_cursor:
            for row in mptz_cursor:
                if (row[1] !=None):
                    row[2] = row[1]/2
                mptz_cursor.updateRow(row)
        arcpy.Buffer_analysis(points,buffer_output,buffer_distance)


@nyc_decorator
def nyc1():
    with arcpy.da.UpdateCursor(Tree_Points,Fields) as nyc_cursor:
        for row in nyc_cursor:
            if (row[0]>0 and row[0] <=10):
                row[1] = (1.5*2)+row[0]/100
            elif (row[0]>=10 and row[0] <=25):
                row[1] = (2.4*2)+row[0]/100
            elif (row[0]>25 and row[0] <=37.5):
                row[1] = (3*2)+row[0]/100
            elif (row[0]>37.5 and row[0] <=50):
                row[1] = (3.6*2)+row[0]/100
            elif (row[0]>50 and row[0] <=70):
                row[1] = (4.5*2)+row[0]/100
            nyc_cursor.updateRow(row)

同样的,你可以定义另外 10 个这样的函数。

@nyc_decorator
def nyc1():
    pass

我发现对理解 programizdoccom 中的装饰器很有用的装饰器的一般示例:

def star(func):
    def inner(*args,**kwargs):
        print("*" * 30)
        func(*args,**kwargs)
        print("*" * 30)
    return inner

@star
def printer(msg):
    print(msg)

printer("Hello")

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Hello
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%