【问题标题】:Using a class vs just functions [closed]使用类与仅使用函数[关闭]
【发布时间】:2018-08-19 03:56:24
【问题描述】:

我将创建一个解析 XML(非常大,0.5gb+)的脚本,并试图思考如何有效地做到这一点。

通常,我会在 AutoIt 中执行此操作,因为这是我用于事物的“普通”语言,但我认为在 Python 中执行此操作更合适(另外我想了解更多 Python)。

通常我会这样做,是创建一个包含我需要从 XML 中的所有“列”的常量,使用它来匹配并将其解析为一个数组(实际上是 2 个数组,子记录的原因),然后将数组集合作为 JSON 对象/字符串传递给记录系统。

在 Python 中,我不确定这是最好的方法。我正在考虑创建一个对象类,然后为我将转换为 JSON 然后提交的 XML 的每个记录/行创建实例。如果我觉得雄心勃勃,我什至会努力让它成为多线程的。我最好的选择是提取一条记录,然后在我处理下一条记录时在后台提交它,最多可以说是 5 到 10 条记录,但这可能不太好。

我的问题是,我使用一个类似乎只是为了使用一个类,或者这似乎是一个很好的理由?我承认我的想法被我之前(根本没有)使用过很多类这一事实所影响,并且正在使用它是因为它整洁而新。

实际上有没有更好的方法让我忽略了,因为我被新的/闪亮的概念蒙蔽了双眼,或者对程序缺乏了解(这可能对我来说很可能)?

我希望得到能够指导我大致方向的答案 - 这是我学习语言的一部分,我自己进行研究真的有助于我理解我在做什么以及为什么。不幸的是,我认为在这一点上我需要一个指南。

【问题讨论】:

  • 不幸的是,这是一个有点宽泛和基于意见的问题,不知道更多细节。如果它可以在有或没有课程的情况下完成,那么就没有明确的答案,你可以选择任何一种方式。既然你正在学习,也许可以尝试两者?

标签: python-3.x theory


【解决方案1】:

这场辩论在本质上主要是情境性的,并且将取决于您打算在您的计划中做什么。我要考虑的主要事情是,我是否需要将属性(数据)功能(方法/函数)封装到一个分组中?

就在这种情况下使用类(对象)的利弊而言,我想到了一些额外的事情:

使用类的原因:

  1. 如果潜在的未来可维护性将保证将新类“交换”到程序中的现有结构中。
  2. 如果存在适用于类的所有实例的属性。
  3. 如果将一组函数与程序的其余部分分开是合乎逻辑的。
  4. 确保不变性的更简洁选项
  5. 为基础字段提供类型与您程序的其余部分非常吻合。

不使用类的原因:

  1. 可以纯粹通过添加新功能来维护代码。
  2. 您没有对存储的字段执行功能性任务(例如存储create_date,但只需要使用age - 这可以更好地用于不公开create_date 的对象,而只是一个函数get_age)。
  3. 您需要满足严格的性能优化标准,并且无法证明调用函数以确保封装、任何额外的内存开销等......

通常,Python 适合使用类,因为它是一种面向对象的语言。但是,与 C++ 和 Java 等更多的 oop 语言相比,您可以在 Python 中“摆脱”更多而不使用类。如果你想探索使用一个类,我当然认为这将是一个很好的语言使用练习。

编辑: 根据后续评论,我想提供一个使用命名参数来实例化具有可选字段的类的示例。一般概述是,Python 在考虑将哪个参数分配给内部功能时解释参数的顺序。举个例子:

def get_info(name, birthday, favorite_color):
   age = current_time - birthday
   return [name, age, favorite_color]

在此示例中,Python 根据调用方法时输入参数的出现顺序来解释输入参数:

get_info('James', '03-05-1998', 'blue')

然而,Python 也允许命名参数,它明确指定参数内部字段分配:

get_info(name='James', birthday='03-05-1998', favorite_color='blue')

虽然乍一看这种语法似乎更冗长,但它实际上提供了很大的灵活性,因为命名参数的顺序无关紧要,您可以为未传递到方法签名中的参数设置默认值:

def get_info(name, birthday, favorite_color=None):
       age = current_time - birthday
       return [name, age, favorite_color]

get_info(name='James', birthday='03-05-1998')

下面我提供了一个更深入的工作示例,说明命名参数如何帮助您在评论中概述的情况(许多字段,并非所有字段都需要)尝试以各种方式构造此对象以看看如何需要非命名参数,但命名参数是可选的,并且默认为__init__() 方法中指定的值:

class Car(object):
    """ Initializes a new Car object. Requires a color, make, model, horsepower, price, and condition.
    Optional parameters include: wheel_size, moon_roof, premium_sound, interior_color, and interior_material."""
    def __init__(self, color, make, model, horsepower, price, condition, wheel_size=16, moon_roof=None, premium_sound=None, interior_color='black', interior_material='cloth'):
        self.color = color
        self.make = make
        self.model = model
        self.horsepower = horsepower
        self.price = price
        self.condition = condition
        self.wheel_size = wheel_size
        self.moon_roof = moon_roof
        self.premium_sound = premium_sound
        self.interior_color = interior_color
        self.interior_material = interior_material

    # Prints attributes of the Car class and their associated values in no specific order.
    def print_car(self):
        fields = []
        for key, value in self.__dict__.iteritems():
            fields.append(key + ': ')
            fields.append(str(value))
            fields.append('\n')
        print ''.join(fields)

# Executes the main program body
def main():
    stock_car = Car('Red', 'Honda', 'NSX', 290, 89000.00, 'New')
    stock_car.print_car()
    custom_car = Car('Black', 'Mitsubishi', 'Lancer Evolution', 280, 45000.00, 'New', 17, "Tinted Moonroof", "Bose", "Black/Red", "Suede/Leather")
    custom_car.print_car()

# Calls main() as the entry point for this program.
if __name__ == '__main__':
    main()

【讨论】:

  • 哇,这是一个很好的答案。我想尝试使用一个类,但到目前为止我遇到的问题是我将拥有 60 个类的“属性”。并不是所有的都有值,所以我真的找不到一个很好的方法来初始化对象,放入 60 个值?
  • @DW 所以我的直觉是像 Java 一样考虑这个,我会使用流畅的接口,或者构建器设计模式来处理许多字段,只有其中一些需要初始化在施工。但是,Python 支持命名参数,这应该只允许您传递您在构造时关心的参数。本质上在一个类中创建所有 60 个字段,但仅在您实际调用该类时初始化您需要的那些。有机会我会用一个例子更新我的答案!
  • 继承真的被高估了——它主要是组合/委托的受限情况——所以我绝对不会把它作为使用或不使用 OO 的第一个驱动力(就我而言,我实际上甚至根本不会提及它)。这里的第一个也是主要驱动力是您是否需要一组函数来处理一组共享数据。
  • @DW 如果你有 60 个候选属性,那么你可能没有正确的设计。
  • @JohnStark 将所有属性标记为受保护并无缘无故地提供 getter 被认为是完全不符合 Python 标准的 - 如果需要,您可以随时将它们转换为计算属性。此外,您可能想了解字符串格式化操作 - 以这种方式连接字符串不可读、容易出错且效率低下。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
  • 1970-01-01
  • 1970-01-01
  • 2014-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多