【问题标题】:Can this block of code be made into a function or simplified in some way? [closed]这段代码可以做成函数或者以某种方式简化吗? [关闭]
【发布时间】:2017-07-06 05:28:53
【问题描述】:

假设我有这个过程:

found = 0
print_header()
for file in files_to_check
    print("Checking file: {}".format(file), end="")
    with open(file) as f:
       line_counter = 0
       for line in f:
            line_counter += 1
            print("-- Checking line: {}".format(line_counter), end="")

            # MY CHECK:
            # Some complex code that either increments "found" or not

            print("done with line")
    print("done with file")
print("FOUND:", found)
print_footer()

假设我想一遍又一遍地这样做。也就是说,我有不同的“检查”要运行。有些很简单,有些很复杂。但它们都有相同的基本结构:遍历每个文件(每次打开或关闭文件时打印一行)和遍历每一行(打印行号),在每一行上做一些事情,然后做在开始下一次迭代之前,每行之后的一些打印和内容。

我希望能够将尽可能多的内容抽象为一个函数或方法(即打印文件名、行计数器、打开和关闭文件、循环遍历每一行),以便我可以定义一个一系列函数(或类),其中包含我检查的核心。

在伪代码中,我会将其视为部分定义的方法,其中中间的“检查”代码将留空。然后我可以根据需要多次实例化这个类,只需将一些自定义代码插入到每个实例的 check() 方法的中间。

在 Python 中可以实现这样的构造吗?我查看了抽象基类,这似乎很有帮助,但似乎没有包含我正在寻找的任何东西。

编辑:

抽象出这段代码的困难(如我所见)是它在一系列文件(with open(file) as f)上运行,然后循环遍历行。上面示例中标记为# MY CHECK 的部分是需要发生许多不同的事情的地方。为了组成一些简单的例子,假设我想遍历每个文件的每一行并且:

  1. 如果此行包含单词“foobar”,则增加一个计数器
  2. 如果该行包含语法“Hello,”,则打印的值
  3. 如果“python”在这一行中,则打印“LAMP”,并且我们已经在文件的前面看到了“Apache”这个词。
  4. ...
  5. ...

但是,我不想对所有文件运行所有这些检查。我可能想运行#1 和#3。明天,为了不同的业务需求,我可能想要运行#1、#4 和#23。因此,我需要将每个“检查”作为自己的功能或自己的方法。

我想要做的不是复制每个检查周围的基础设施(设置文件、打开文件、打印页眉和页脚等)

【问题讨论】:

  • 是的,你可以把它放到一个函数中……你试过了吗,你遇到了什么问题?复杂的代码到底是什么?
  • 每个抽象层次都应该放在不同的函数中。
  • 我不确定抽象基类如何帮助您,甚至是类。您的代码似乎非常适合一个函数。也许你不知道,但函数是 Python 中的一等对象,可以作为参数传递给函数,也可以从函数返回。
  • 你可以将整个代码作为一个函数接收检查函数 def check_in_files(checker): # your code # MY CHECK: found += 1 if checker(line) else 0 # rest代码 def check1(line): #some code 你可以称之为check_in_files(check1)
  • 该问题已被编辑以进一步解释“检查”过程。

标签: python function loops methods abstract-class


【解决方案1】:

函数是 Python 中的一等对象。 由于每个检查器基本上只需要一个参数(要检查的行),因此您可以使用检查器函数作为循环函数的参数。

def test(filename, function):
    with open(filename) as foo:
        for line in foo:
            rv = function(line)
            print(function.__name__, 'returned:', rv)

【讨论】:

  • 啊!这很有帮助 - 谢谢。
【解决方案2】:

使用函数作为参数:

def file_checker(files_to_check, checker):
    found = 0
    print_header()
    for file in files_to_check:
        print("Checking file: {}".format(file), end="")
        with open(file) as f:
            for num, line in enumerate(f, 1):
                print("-- Checking line: {}".format(num), end="")
                if checker(line):
                    found += 1
                print("done with line")
        print("done with file")
    print("FOUND:", found)
    print_footer()
    return found

或生成器:

def multi_file_line_iterator(files_to_check):
    print_header()
    for file in files_to_check:
        print("Checking file: {}".format(file), end="")
        with open(file) as f:
            for num, line in enumerate(f, 1):
                print("-- Checking line: {}".format(num), end="")
                yield line
                print("done with line")
        print("done with file")
    print("FOUND:", found)
    print_footer()
    return found

found = 0
for line in multi_file_line_iterator(files_to_check):
    found += checker(line)

【讨论】:

  • 感谢您的详细建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多