Python语句作为方法的参数

时间:2016-04-06 16:26:26

标签: python path

下面我有两个代码块 - 除了一行 - 其余的都是相同的。

for id in ids_list:
    id_dir = os.path.join(dir, id)
    os.chdir(id_dir)
    for path in glob('*' + file_extention):
        with open(path) as file:
        # count number of lines in file
            names[path] = sum(1 for line in file if line.strip())

for id in ids_list:
    id_dir = os.path.join(dir, id)
    os.chdir(id_dir)
    for path in glob('*' + file_extention):
        with open(filepath) as file:
            # get file content
            content = file.read()

我想知道是否有办法创建一个方法(可能会有ids_listfile_extention,当然还有语句(要么计算行数或获取内容)作为参数。我正在努力解决如何使用语句。任何帮助,特别是用一些示例代码说明,因为我是Python新手会很棒。

4 个答案:

答案 0 :(得分:2)

这可以通过将一个函数作为参数传递给另一个函数来完成。

def last_line():
    content = file.read()

def do_last_line(func):
    for id in ids_list:
        id_dir = os.path.join(dir, id)
        os.chdir(id_dir)
            for path in glob('*' + file_extention):
                with open(filepath) as file:
                    func()

do_last_line(last_line)

应该这样做,尽管content变量在函数外部不可用。你可以退货。

另一种方法是使用exec()或eval(),但这通常被认为是不好的做法。

答案 1 :(得分:2)

使用回调函数的时间

您的情况是使用回调函数可以提供帮助的情况。

通常,回调是具有约定参数的函数,有时也返回值。该 回调函数作为参数传递给另一个函数,该函数调用它同意传递 它的参数并将处理留给回调函数。

为了让您的代码正常工作,我不得不对其进行一些修改。所有代码都来自一个文件,例如有名字 “et.py”

为了解释它,我会一点一点地展示它。

进口

import os
from glob import glob

回调处理从文件中读取的内容

你的例子是将值读入content变量,每个循环用新值重写它,所以 最后,你只有最后的价值。

我通过添加全局变量GLOB_CONTENT来修改代码,我追加了它 每个文件的内容一个接一个。

GLOB_CONTENT = []


def read_file_content(path):
    global GLOB_CONTENT
    with open(path) as f:
        # get file content
        content = f.read()
        # do some content processing here
        GLOB_CONTENT.append(content)

全局变量的使用有时是可疑的,但它是保持全局状态的一种方式 东西。

对行进行回调 - 使用“memory”

任何函数都可以用作回调(如果它遵循预期的签名)。一个案例是 类实例的方法。它将从dict派生,以便能够记住下的某些值 密钥名称,它将添加方法count_file_lines,作为文件的参数名称:

class FilesLineCounter(dict):
    def count_file_lines(self, path):
        with open(path) as file:
            self[path] = sum(1 for line in file if line.strip())

它会计算文件中的非空行并记住它本身。

处理文件的功能

循环可以推广到函数中:

def process_ids(dir_path, ids_list, file_extension, callback):
    for itm_id in ids_list:
        id_dir = os.path.join(dir_path, itm_id)
        for path in glob(id_dir + '/*' + file_extension):
            callback(path)

如您所见,它获取了查找正确文件所需的所有参数,以及使用的callback函数 处理找到的文件。

最后:把它们放在一起

以下是代码的最后一部分:

if __name__ == "__main__":
    dir_path = "subdir"
    ids_list = ["1", "2"]
    file_extension = ".txt"

    cntr = FilesLineCounter()
    # goint to use the callback magic
    process_ids(dir_path, ids_list, file_extension, cntr.count_file_lines)
    process_ids(dir_path, ids_list, file_extension, read_file_content)

    # time to show our results
    for path, numoflines in cntr.items():
        print("File {} has {} lines".format(path, numoflines))

    for i, content in enumerate(GLOB_CONTENT):
        print("File # {} last 3 bytes are {}".format(i, content[-3:]))

cntr = FilesLineCounter()创建了我们特殊的扩展字典。 cntr为空 已添加方法count_file_lines的字典。由于该方法可用作函数,我们使用 cntr.count_file_lines作为回调的价值。

process_ids处理它时,我们会在cntr中找到每个已处理文件的一个密钥,每个 具有该文件中非空行数的值。

同样,我们阅读了内容。

运行$ python et.py我得到以下输出:

File subdir/1/one-plus.txt has 1 lines                                                                                                                                                                      
File subdir/2/empty.txt has 0 lines                                                                                                                                                                               
File subdir/1/one.txt has 8 lines                                                                                                                                                                                 
File subdir/2/long.txt has 42 lines                                                                                                                                                                               
File # 0 last 3 bytes are fa                                                                                                                                                                                      

File # 1 last 3 bytes are hi                                                                                                                                                                                      

File # 2 last 3 bytes are fa                                                                                                                                                                                      

File # 3 last 3 bytes are 

答案 2 :(得分:2)

倒置解决方案 - 生成器

如我的另一个答案中所述,不是使用回调,而是可以反转解决方案。

我们可能会在循环内部循环path值而不是调用某些函数 创建一个生成器,产生path值并让代码执行任何要做的事情。

import os
from glob import glob


def files_to_process(dir_path, ids_list, file_extension):
    for itm_id in ids_list:
        id_dir = os.path.join(dir_path, itm_id)
        for path in glob(id_dir + '/*' + file_extension):
            yield path

if __name__ == "__main__":

    dir_path = "subdir"
    ids_list = ["1", "2"]
    file_extension = ".txt"

    names = {}
    # using the generator first time
    for path in files_to_process(dir_path, ids_list, file_extension):
        with open(path) as f:
            names[path] = sum(1 for line in f if line.strip())

    glob_content = []
    # using the generator the second time
    for path in files_to_process(dir_path, ids_list, file_extension):
        with open(path) as f:
            glob_content.append(f.read())
            names[path] = sum(1 for line in f if line.strip())


    for path, numoflines in names.items():
        print("File {} has {} lines".format(path, numoflines))

    for i, content in enumerate(glob_content):
        print("File # {} last 3 bytes are {}".format(i, content[-3:]))

函数files_to_process是生成器。 调用files_to_process(dir_path, ids_list, file_extension)即可获得生成器值。 如果迭代它,它将返回(yield)它找到的所有值到循环。

警告:生成器可能已耗尽。这意味着,一旦它产生一个值,下一次就会产生 产生另一个,直到没有更多的东西可以产生,你就得不到更多的价值。

要再次获取值,您必须再次创建生成器。

对我来说,带生成器的代码似乎更具可读性。

答案 3 :(得分:0)

当然你可以有一个方法     '读取文件(IDs_list,ext,type):'      ....         'if type == get:'              '在这里得到代码'         '其他:'              '其他代码在这里'