【问题标题】:11 functions with duplicate lines of code - is there a way to reduce the redundancy?11 个具有重复代码行的函数 - 有没有办法减少冗余?
【发布时间】:2021-01-04 05:28:09
【问题描述】:

我正在使用带有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', 'MTPZ_Buffer']
    buffer_output = arcpy.GetParameterAsText(3)
    buffer_distance = "MTPZ_Buffer"

还有:

    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)

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

【问题讨论】:

  • 重复的代码行通常被包装到一个函数中。这是基本的编程设计。
  • 也可以将不同的行封装在单独的函数中,将函数引用传递到普通函数中进行普通处理。
  • @Rahul 有一个很好的答案,显示了我在说什么。
  • 请从intro tour 重复on topichow to ask。您要求个人掌握许多其他资源中包含的技能。这超出了 Stack Overflow 的范围。

标签: python python-2.7 arcpy code-duplication redundancy


【解决方案1】:

你可以试试装饰器。目前尚不清楚您要传递哪些参数和变量范围,但您可以尝试类似的方法。

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
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

【讨论】:

  • 您可能需要了解 python 装饰器的工作原理。出于这个特殊原因,我给出了上面的一般示例以使您理解。
  • 它运行被修饰的函数。只需查看提供的星号和打印机功能示例。
  • 一般情况下不要将函数放入 if elif 块中。您只需定义它们。根据条件,您只需在 if elif 块中运行它们。
猜你喜欢
  • 1970-01-01
  • 2011-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-25
  • 2017-01-13
相关资源
最近更新 更多