【问题标题】:How to split code into smaller functions如何将代码拆分为更小的函数
【发布时间】:2015-05-20 05:11:19
【问题描述】:

我有一个可以运行的应用程序。但是为了更好地理解函数和 python。我正在尝试将其拆分为各种功能。

我卡在 file_IO 函数上。我确定它不起作用的原因是因为应用程序的主要部分不理解 reader 或 writer。为了更好地解释。这是应用程序的完整副本。

我也对使用 csv.DictReader 和 csv.DictWriter 感到好奇。是否对当前代码提供任何优点/缺点?

我想另一种方法是通过类,老实说我也想知道如何做到这一点。

#!/usr/bin/python

""" Description This script will take a csv file and parse it looking for specific criteria.  
A new file is then created based of the original file name containing only the desired parsed criteria.
"""

import csv
import re
import sys

searched = ['aircheck', 'linkrunner at', 'onetouch at']

def find_group(row):
    """Return the group index of a row
        0 if the row contains searched[0]
        1 if the row contains searched[1]
        etc
        -1 if not found
    """
    for col in row:
        col = col.lower()
        for j, s in enumerate(searched):
            if s in col:
                return j
        return -1



#Prompt for File Name
def file_IO():
    print "Please Enter a File Name, (Without .csv extension): ",
    base_Name = raw_input()
    print "You entered: ",base_Name

    in_Name = base_Name + ".csv"
    out_Name = base_Name + ".parsed.csv"

    print "Input File: ", in_Name
    print "OutPut Files: ", out_Name

    #Opens Input file for read and output file to write.
    in_File = open(in_Name, "rU")
    reader = csv.reader(in_File)

    out_File = open(out_Name, "wb")
    writer = csv.writer(out_File, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)

    return (reader, writer)

file_IO()

# Read header
header = reader.next()


stored = []
writer.writerow([header[0], header[3]])

for i, row in enumerate(reader):
    g = find_group(row)
    if g >= 0:
        stored.append((g, i, row))
stored.sort()

for g, i, row in stored:
    writer.writerow([row[0], row[3]])


# Closing Input and Output files.
in_File.close()
out_File.close()

【问题讨论】:

  • 你有很多问题,其中一些对于 SO 来说是题外话(太宽泛)。请简化和澄清一个问题。
  • 如果你可以让你的代码工作,那么关于清理它和改进样式的问题更适合 codereview 网站:codereview.stackexchange.com
  • 好吧,那么现在的问题就是。使用当前代码,我收到以下错误消息 ./test.py Please Enter a File Name, (Without .csv extension): YouTubeVideoViewsDec2014 You enter: YouTubeVideoViewsDec2014 Input File: YouTubeVideoViewsDec2014.csv OutPut Files: YouTubeVideoViewsDec2014.parsed.csv Traceback (most最近通话最后):文件“./test.py”,第 56 行,在 header = reader.next() NameError: name 'reader' is not defined
  • 对于它的价值,我在这里写成函数的唯一代码是find_group
  • @KrisArmstrong 您的代码抛出特定错误的原因是,正如您在问题文本中提到的那样,您的主代码不知道 readerwriter 是什么,因为它们是作用于代码块。你返回(reader, writer) 这很好,但是当你调用函数时你必须分配它们,例如reader, writer = file_IO()。也就是说,以这种方式关闭这些文件处理程序将非常困难。我不会这样做。

标签: python function class csv


【解决方案1】:

如果我是你,我只会分开find_group

import csv

def find_group(row):
    GROUPS = ['aircheck', 'linkrunner at', 'onetouch at']
    for idx, group in enumerate(GROUPS):
        if group in map(str.lower, row):
            return idx
    return -1

def get_filenames():
    # this might be the only other thing you'd want to factor
    # into a function, and frankly I don't really like getting
    # user input this way anyway....
    basename = raw_input("Enter a base filename (no extension): ")
    infilename = basename + ".csv"
    outfilename = basename + ".parsed.csv"
    return infilename, outfilename
    # notice that I don't open the files yet -- let main handle that

infilename, outfilename = get_filenames()

with open(infilename, 'rU') as inf, open(outfilename, 'wb') as outf:
    reader = csv.reader(inf)
    writer = csv.writer(outf, delimiter=',',
                        quotechar='"', quoting=csv.QUOTE_ALL)
    header = next(reader)
    writer.writerow([[header[0], header[3]])
    stored = sorted([(find_group(row),idx,row) for idx,row in
                     enumerate(reader)) if find_group(row) >= 0])
    for _, _, row in stored:
        writer.writerow([row[0], row[3]])

【讨论】:

  • 唯一让我难以理解的行是 storage = sorted([(find_group(row),idx,row) for idx,row in enumerate(reader)) if find_group (行)])我认为这只是导致它的一条长线。用户输入通常是从 main 收集的吗?好奇的是,功能与主要的用户输入是否有任何优点/缺点。可能。那将是最好的解决方案。另外,如果我在 Python 3.4.3 sop 中工作很重要,那么 raw_input() 已更改为简单的 input() 感谢您的帮助。这确实简化了原始代码。
  • 对于reader 中的每一行,它为(index_of_row, row) 执行for 循环。如果find_group(row) >= 0(也就是说,它在该行中找到了您的组之一),它会将元组(find_group(row), index_of_row, row) 添加到结果列表中。这一切都包含在sorted 调用中,所以整个事情都是按组排序的。
  • 请注意,我确实在该代码中犯了一个错误——if find_group(row) 应该是 if find_group(row) >= 0。原始代码将列出所有未找到的行,或者找到除aircheck 以外的其他内容(因为找到aircheck 将返回0
  • 我使用了raw_input,因为如果您的示例代码,YOU 使用了raw_input。其他一切都没有改变。
  • 该行相当于following for loop
猜你喜欢
  • 2012-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-13
  • 2016-10-28
  • 1970-01-01
相关资源
最近更新 更多