我是 OOP 的初学者,我想创建一个包含三个类 A、B 和 C 的程序。类的每个实例都由一组特征 Achar1、Achar2 等定义。
该程序应该创建使用,包括 A 的元素、B 的元素和 C 的元素以及开始和结束日期。 A和B有子类,使得A的某些元素只能连接到B的某些元素。程序的主要功能是列出A、B和C的元素及其属性,list uses 并建议新的用途,这些实例将使用最少的类实例以避免重复。
我的第一直觉是使用 A、B 和 C 三个词典和一个 uses 词典。这看起来很直观,也很容易导入/导出到 json 或类似文件中。我试图重写它以使用类,但我看不到这样做有任何好处:很难(?)迭代类的实例,而且它们基本上是字典,因为这些数据不需要太多其他东西。
我做错了什么?从字典切换到对象可以获得什么?
最佳答案
从字典切换到对象有什么好处?
这是一个相当大的问题。
在 Python 中,对象在语义上等同于字典是正确的,因为对象几乎等同于它的 __dict__
。属性(我不会在这里详细说明这个“几乎”,因为它离主题很远)。
我看到使用类而不是字典的两个主要好处:抽象和舒适。
抽象
当您处于设计阶段时,尤其是对于中短长度的程序,您通常希望一边思考一边编写代码的框架。
在需要对交互进行建模的情况下,在类里面思考更为自然,因为它介于口语和编程之间。
这使您更容易理解自己的问题。此外,它极大地提高了代码的可读性,因为它看起来很自然,即使读者对您的代码一无所知。
这为您带来了继承和多态性等概念,丰富了 OOP 提供的抽象。
舒适
Python 的众多优势之一是它的 data model .大量神奇的方法和属性允许您使用非常简单的语法。此外,它还可以代替您处理一些操作。
以下是 Python 中命令式编程和面向对象编程之间的一些比较。
当然,Python 中的一切都是对象,因此即使在命令式示例中我也会使用点调用 ( foo.bar()
)。
文件阅读
命令式
f1 = open(in_path, 'r')
f2 = open(out_path, 'w')
for line in f1:
processed = process(line)
f2.write(processed)
# Oops, I forgot to close my files...
面向对象的方式
with open(in_path, 'r') as f1, open(out_path, 'w') as f2:
for line in f1:
processed = process(line)
f2.write(processed)
# I don't have to close my files, Python did it for me
请注意 for line in f
是大量使用Python的面向对象的数据模型。想象一下如果不存在这种语法会很痛苦(好吧,只需在 C 中尝试一下)。
空性测试
命令式
if len(some_list) == 0:
print("empty list")
面向对象的方式
if some_list:
print("empty list")
迭代一个序列
命令式
i = 0
while i < len(some_sequence):
print(some_sequence[i])
i += 1
面向对象的方式
for elt in some_sequence:
print(elt)
但是这个数据模型的真正优势在于它可以让你重新定义很多神奇的属性。例如,您可以通过实现 __lt__
来使复杂的事物具有可比性。 , __le__
等等,这将重新定义 <
的行为, <=
, 等等。从那时起,内置函数如 min
, max
或 sort
将了解如何比较您的对象。
也就是说,在很多情况下,仅使用字典就足够了。
归根结底,OOP 只是一种范式,命令式编程也能正常工作。
关于Python OO程序结构规划,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41660924/