如何从Python中类外部的通用方法初始化在类级别定义的列表?

问题描述 投票:0回答:1

我在 Python 中的类级别定义了一个列表,下面是我的代码:

class TestStudentReg(unittest.TestCase):
    student_id_list = []  

我正在尝试通过从 csv 文件读取值来初始化列表,下面是我在同一类中使用的方法,即 TestStudentReg

@classmethod
def initialise_student_id_list(cls):
    filename = 'input/student_testdata.csv'        
    with open(filename, 'r') as csvfile:
        datareader = (csv.reader(csvfile, delimiter="|"))
        next(datareader, None)  # skip the headers
        for col in datareader:
            cls.student_id_list.append(col[2])

现在这个方法在多个类中很常见,我计划将其作为可重用的函数并将其定义在一个单独的 python 文件(utilities.py)中,如下所示:

import csv
import logging
import time
import timeit

def get_date(dateformat="%Y-%m-%d", subtract_num_of_days=0):
   getdate = date.today() - timedelta(subtract_num_of_days)
   return getdate.strftime(dateformat)

def initialise_student_id_list(**kwargs):  
    filename = 'input/student_testdata.csv'      
    with open(filename, 'r') as csvfile:
        datareader = (csv.reader(csvfile, delimiter="|"))
        next(datareader, None)  # skip the headers
        for col in datareader:
            cls.student_id_list.append(col[2])

我想了解如何从实用程序文件中初始化student_id_list。

我认为实现此目的的一种方法是让该方法返回一个列表并通过调用此方法来初始化该值。

def initialise_student_id_list(**kwargs):  
        id_list=[] 
        filename = 'input/student_testdata.csv'     
        with open(filename, 'r') as csvfile:
            datareader = (csv.reader(csvfile, delimiter="|"))
            next(datareader, None)  # skip the headers
            for col in datareader:
                cls.student_id_list.append(col[2])
        return id_list

不确定这是否是正确的方法。如果有人能帮助我,那就太好了。

python python-3.x
1个回答
0
投票

有多种方法可以解决您的问题。在这里我将列出三个可读性和整体质量不断提高的:

def student_id_list_initialiser(class_obj, **kwargs):
    cls = class_obj   
    filename = 'input/student_testdata.csv'      
    with open(filename, 'r') as csvfile:
        datareader = (csv.reader(csvfile, delimiter="|"))
        next(datareader, None)  # skip the headers
        for col in datareader:
            cls.student_id_list.append(col[2])

class MyTest():
    student_id_list = []
    
    @classmethod
    def initialise_student_id_list(cls):
        student_id_list_initialiser(cls)

这种方法工作得很好,但它不是最好的,因为我们必须手动传入类对象,并且代码破坏了封装。然而,如果再加上一个简单而简短的类方法来设置类变量

student_id_list
,那就更好了:

def student_id_list_creator(**kwargs):
    ret_l = []
    filename = 'input/student_testdata.csv'      
    with open(filename, 'r') as csvfile:
        datareader = (csv.reader(csvfile, delimiter="|"))
        next(datareader, None)  # skip the headers
        for col in datareader:
            ret_l.append(col[2])
    return ret_l

class MyTest():
    student_id_list = []
    
    @classmethod
    def initialise_student_id_list(cls):
        cls.student_id_list = student_id_list_creator()

这和你说的想法类似,是的,这确实是一个很好的做法。 最后,继承也许是最好的选择,尽管不是从

TestStudentReg
类直接继承。这是代码:

class StudentInfoHelper():
    @classmethod
    def initialise_student_id_list(cls):
        filename = 'input/student_testdata.csv'        
        with open(filename, 'r') as csvfile:
            datareader = (csv.reader(csvfile, delimiter="|"))
            next(datareader, None)  # skip the headers
            for col in datareader:
                cls.student_id_list.append(col[2])

class TestStudentReg(StudentInfoHelper):
    student_id_list = []

# outside:
TestStudentReg.initialise_student_id_list()

这段代码不仅可读性更强,而且更加灵活,可以应用于任何继承自

StudentInfoHelper
的类。这种方法的唯一缺点是

  1. 您必须将类变量命名为
    student_id_list
    。但既然你已经决定了变量名,那就不是问题了。
  2. 如果你定义一个名为
    student_id_initialiser
    的方法,它将不起作用。原因很明显:因为如果你这样做,那么原始方法将被新方法“遮蔽”。但有时,如果您想自定义方法或不需要它,这也是一件好事。
© www.soinside.com 2019 - 2024. All rights reserved.