这段代码可以用某种方式制作成函数还是简化?

时间:2017-02-16 21:41:11

标签: python function loops methods abstract-class

假设我有这个过程:

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. ,则增加一个计数器
  3. 如果该行包含语法“Hello,”
  4. ,则打印该值
  5. 如果单词“python”在此行中,则打印“LAMP”,我们之前已在文件中看到“Apache”一词。
  6. ...
  7. ...
  8. 但是,我不想对所有文件运行所有这些检查。我可能想要运行#1和#3。明天,为了满足不同的业务需求,我可能希望运行#1,#4和#23。因此,我需要将每个“检查”作为自己的函数或自己的方法。

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

2 个答案:

答案 0 :(得分:2)

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

https://sambaza.herokuapp.com/

答案 1 :(得分:2)

使用函数作为参数:

from keyboard import on_press, on_release, wait
from win32gui import GetWindowText, GetForegroundWindow
from datetime import datetime

def display(event, key):
    global ctrlpressed, shiftpressed, lastwindow
    if lastwindow != GetWindowText(GetForegroundWindow()):
        lastwindow = GetWindowText(GetForegroundWindow())
        print("New Window: " + lastwindow)
    print('{0:8} {1:3} {2:5} {3:5} {4}'.format(datetime.fromtimestamp(event.time).strftime('%H:%M:%S'), event.scan_code, str(ctrlpressed), str(shiftpressed), key))

def KeyPressed(event):
    global ctrlpressed, shiftpressed
    if(event.name == 'left shift' or event.name == 'right shift'):
        shiftpressed = True;
    elif(event.name == 'left ctrl' or event.name == 'right ctrl'):
        ctrlpressed = True;
    else:
        display(event, event.name)

def KeyReleased(event):
    global ctrlpressed, shiftpressed
    if(event.name == 'left shift' or event.name == 'right shift'):
        shiftpressed = False;
    elif(event.name == 'left ctrl' or event.name == 'right ctrl'):
        ctrlpressed = False;

ctrlpressed = shiftpressed = False;
lastwindow = "";
on_press(KeyPressed)
on_release(KeyReleased)
wait()

或发电机:

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