python新手问题:将代码转换为类

python新手问题:将代码转换为类,python,class,csv,Python,Class,Csv,我有以下代码: import csv import collections def do_work(): (data,counter)=get_file('thefile.csv') b=samples_subset1(data, counter,'/pythonwork/samples_subset3.csv',500) return def get_file(start_file): with open(start_file, 'rb

我有以下代码:

import csv
import collections

def do_work():
      (data,counter)=get_file('thefile.csv')
      b=samples_subset1(data, counter,'/pythonwork/samples_subset3.csv',500)
      return

def get_file(start_file):

        with open(start_file, 'rb') as f:
            data = list(csv.reader(f))
            counter = collections.defaultdict(int)

            for row in data:
              counter[row[10]] += 1
            return (data,counter)

def samples_subset1(data,counter,output_file,sample_cutoff):

      with open(output_file, 'wb') as outfile:
          writer = csv.writer(outfile)
          b_counter=0
          b=[]
          for row in data:
              if counter[row[10]] >= sample_cutoff:
                 b.append(row) 
                 writer.writerow(row)
                 b_counter+=1
      return (b)

我最近开始学习python,并希望从良好的习惯开始。因此,我想知道您是否可以帮助我开始将这些代码转换为类。我不知道从哪里开始。

嗯,我不确定你想把什么变成一门课。你知道什么是班级吗?您希望创建一个类来表示某种类型的事物。如果我正确理解您的代码,您希望筛选CSV以仅显示其
行[10]
至少被
示例\u截止
其他行共享的行。当然,使用Excel过滤器比用Python读取文件更容易做到这一点

另一个帖子中的那个家伙所建议的是正确的,但并不真正适用于你的情况。您不必要地使用了很多全局变量:如果代码中需要这些变量,那么您应该将所有内容都放入一个类中,并将它们设置为属性,但由于您一开始并不需要它们,因此创建一个类是没有意义的

有关代码的一些提示:

  • 不要将文件强制转换为列表。这使得Python可以立即将整个内容读取到内存中,如果您有一个大文件,这是不好的。相反,只需遍历文件本身:
    对于csv.reader(f)中的行:
    然后,当您想再次遍历文件时,只需执行
    f.seek(0)
    即可返回顶部并重新开始

  • 不要将
    return
    放在每个函数的末尾;那是没有必要的。您也不需要括号:
    returnspam
    就可以了

重写
根据我在原始帖子上的评论,我认为这里不需要上课。尽管如此,如果其他Python程序员会读到这篇文章,我还是建议将它与Python风格指南PEP8结合起来。下面是一个快速重写:

import csv
import collections

def do_work():
    data, counter = get_file('thefile.csv')
    b = samples_subset1(data, counter, '/pythonwork/samples_subset3.csv', 500)

def get_file(start_file):
    with open(start_file, 'rb') as f:
        counter = collections.defaultdict(int)
        data = list(csv.reader(f))

        for row in data:
            counter[row[10]] += 1

    return (data, counter)

def samples_subset1(data, counter, output_file, sample_cutoff):
    with open(output_file, 'wb') as outfile:
        writer = csv.writer(outfile)
        b = []
        for row in data:
            if counter[row[10]] >= sample_cutoff:
                b.append(row) 
                writer.writerow(row)

    return b
注:

  • 没有人使用超过4个空格来 永远缩进。使用2-4。诸如此类 你的缩进水平应该 匹配
  • 在参数之间的逗号后使用单个空格 对功能(“F(a,b,c)”不适用 “F(a,b,c)”)
  • 函数末尾的裸返回语句 这些都是毫无意义的。无功能 return语句隐式返回
    None
  • 全方位单空间 运算符(a=1,不是a=1)
  • 不要 将单个值括在括号中。 它看起来像一个元组,但它不是
  • b_柜台根本没用,所以我 移除它
  • csv.reader返回一个迭代器,您将其强制转换到列表中。这通常不是一个好主意,因为它迫使Python立即将整个文件加载到内存中,而迭代器只会根据需要返回每一行。理解迭代器对于编写高效的Python代码是绝对必要的。现在我已经将
    数据
    留在了中,但是您可以重写以在使用
    数据
    的任何地方使用迭代器,这是一个列表

  • 这家伙提出了这样的建议:虽然我可以提出很多挑剔的风格建议,但我同意,对于这么小的程序来说,上课并不是真的必要。tiptych,你能提出这些建议吗?我很高兴听到他们的建议。你的代码看起来不错。那个家伙说得对,类比全局变量好。但是这段代码没有错。@Jason:当然,这段代码没有错,它是由SO编写的!在OP的历史上有一个高峰。谢谢。excel不是此作业的合适工具。与python相比,vba是一块垃圾:)100%同意。到目前为止,您在原始代码中所做的是创建只对作为输入提供给它们的内容做出良好反应的函数,并且只对它们将作为值返回的内容产生影响。这本身就是一件好事;)将其设为一个类会重新引入一种危险,即操作变量的方式不如您现在所做的那么明显,而状态的复杂性还不足以让您同时受益。您确定Excel不是这项工作的合适工具吗?我不是说你应该用VBA写宏(啊!!!)!您正在进行数据筛选:仅当
    =COUNTIF(K1:K,Kn)>=sample\u cutoff
    时,才显示第n行。我肯定是的,因为我在这方面有很多经验。你真的读过我写的吗?我会告诉你:Excel可以做到这一点,而且非常简单。步骤1:在CSV中创建一个新列,公式为
    =COUNTIF(K1:K,Kn)>=sample_cutoff
    。步骤2:数据->自动筛选。步骤3:在新列的顶部,单击下拉菜单按钮并选择TRUE。完成了,没有涉及Python。这部分对我不起作用:对于csv.reader(f)中的行,它不返回任何内容。我的错误-没有注意到您正在返回
    数据
    变量。这就改变了一切。@l\uuuu:要摆脱列表强制转换,只需执行
    data=csv.reader(f)
    。然后,除了将
    数据
    传递给
    示例_subset1
    ,传递
    f
    并调用
    f.seek(0)
    ,然后再次遍历它。katriealex,你能给我一个例子说明我如何通过f.seek(0)吗?文件“C:\pythonwork\readthefile072810.py”,第6行,在dou-work中b=samples\u subset1(数据,计数器,/pythonwork/samples\u subset4.csv',500,f)文件“C:\pythonwork\readthefile072810.py”,第23行,在samples\u subset1 f.seek(0)中ValueError:对关闭的文件执行I/O操作
    import csv
    import collections
    
    def do_work():
        data, counter = get_file('thefile.csv')
        b = samples_subset1(data, counter, '/pythonwork/samples_subset3.csv', 500)
    
    def get_file(start_file):
        with open(start_file, 'rb') as f:
            counter = collections.defaultdict(int)
            data = list(csv.reader(f))
    
            for row in data:
                counter[row[10]] += 1
    
        return (data, counter)
    
    def samples_subset1(data, counter, output_file, sample_cutoff):
        with open(output_file, 'wb') as outfile:
            writer = csv.writer(outfile)
            b = []
            for row in data:
                if counter[row[10]] >= sample_cutoff:
                    b.append(row) 
                    writer.writerow(row)
    
        return b