如题。本人本身对 Python 语言很喜欢,阅读过《流程的 Python 》、《 Python 工匠》,尝试过钻研一些 Python 的进阶特性,但本人本身是学生,没有任何业务实战经验,只会调一些机器学习、深度学习常用的库,例如 Pandas 、PyTorch 、Transformers 。
一直对面向对象的思想很着迷,了解过 SOLID 原则,平时写代码也会训练自己注意这些,但不熟悉 23 种设计模式,只略有耳闻。平时写代码,喜欢把代码封装成类。但是总觉得自己在“自嗨”,每次把一些代码封装并调试好之后,都有一种失落感,好像自己什么也没干。
感觉很多 Python 的读物,都教了 Python“面向对象”的知识,但我始终不知道,什么时候该用“面向对象”,以及为什么要用“面向对象”。
问题描述的可能不太完整,但希望站内的大佬不吝赐教,感谢!

道法自然,多看看 Python 比较流行的库别人是怎么做的,你就会明白,python 想怎么写就怎么写,变量想怎么命名就怎么命名🤔

开个玩笑,认真的, 想学面对对象,就多看看 java 的一些源码,比如 spring 全家桶,

抽象化是软件工程要注意的事。之所以产生专门软件工程的学问就是一个人和一群人写代码要注意的情况是不同的,一百行代码和一万行代码要注意的情况也是不同的。op 觉得封装在“自嗨”,很可能就是目前项目的规模(组内人员数、代码规模)还没有达到必要封装的数量级。

oop 还是得看 java , 所有东西都得写个 class
设计思想和设计模式 只是为了让代码更好维护,更好重用,不是为了让代码更容易理解
就是 oop 孔乙己口中的 “高内聚,低耦合”
但是了解这设计模式后,确实是会一下 get 到程序的框架, 就好像看到 foo bar 就知道这个是测试代码
使用一些库或框架,你学了它的用法,就学到设计模式了,它无处不在, 相逢何必曾相似
你且先去模仿罢

oop 适合给商业公司分锅堆屎山,自己写东西别沾那套

当变量有一组行为的时候就说明它应该用类实现

听你的描述,你做的工作其实是调参,一个脚本一个 function 就能解决,自然不需要类,类涉及到领域抽象。

写得太少, 看得也少.
首先不用看什么设计模式, 那是基于 Java 特性编的, 你看除了 Java 还有哪些语言天天讲依赖注入来做控制反转的, 我们 Python 直接把函数当参数传过去就做完控制反转了.
然后可以看看优秀的开源库, 比如 requests 这种, 也可以看看大公司开源出来的 sdk 都是这么组织代码的.
最后, 写多了改多了自然就懂了.

拿编程作为科研工具,自然是没办法学到工程化的技能。得写面向实际使用的业务功能。

还是写的不够多。我写了快五年 Python 了,没有系统看过这些书,中间尝试过很多风格,最后才按照自己的喜好和习惯慢慢固定到一种风格上。只要你保证写完很长时间以后自己能看懂,就行。

如果你学了软件工程就会知道, 先面向对象分析,然后面向对象设计,最后才是面向对象编程,只知道面向对象编程意义不是很大
如果你掌握多种语言(比如 c++、java 、python )就会知道,不同语言中的面向对象实现是不一样的,一些思想细节也是不一样
至于设计原则、高内聚低耦合这些的前提是代码需要维护、修改、协作,特点是人多、代码多、逻辑复杂、时间跨度大、水平差距大,如果是一个人、少量代码、不需要反复修改,不好体会到好处。所以

具体到 Python 语言,用不用面向对象,和用不用class 关系不大,所以他不是一个语法的事情,而是一个思想的事情,如果回到第一句,在分析和设计时用采用面向对象方法,写代码就可以很自然实现面向对象(不论用不用 class 语法)

面向对象、设计模式是前辈根据工程实践提出的方法论,不必刻意追求这些,
代码写多了看多了,有了自己的思路和方法论,就好理解这些别人提出的经典方法论了(当然,你带着这样的疑惑不断思考,也是一种精进)

多改屎山,这样你才知道什么是 bad smell ,在自己写到时候才会第一时间反应这么写有 bad smell ,应该设计一下
现在你的代码的量应该不需要设计,能用就完了

怀疑你可能光看书而缺少实践
自己写点实用的小工具,多写代码(最好是生活中遇到的问题),遇到不知道怎么处理、设计的情况,再去看书
为什么要用面向对象或设计模式,这些都是抽象的方法,但是也并不是所有情况都适用的。个人认为要说有什么代码设计中的核心原则的话,那就是 DRY ( Don't Repeat Yourself ),很多东西都是为了避免重复的,比如多个地方出现的重复的逻辑,就想办法把它们抽象成函数或类。
那为什么要避免重复呢,这是为了方便修改,未来可能出现新的需求,要改的话只改一处地方就好了。

之前写 java 的,现在写 python ,真的也很迷,到底什么时候用对象😂

一般来说,搞 ML 的代码写的一般都会比较随意(无贬义),因为大部分时候没必要写那么好。根本在于代码主要是为了做实验,不需要长期维护。所以如果想找一些 best practice, 就找哪些非 ML 且长期维护的 Python 库参与贡献比较好。

ML 和软件工程没什么共性的,虽然他们都写 python ,但完全是两个东西

结论就是,ML 那帮人只是需要一些写起来简单的让 CPU / GPU 完成运算的“命令” 罢了,python 只是恰好因为语法直观以及胶水的特性满足他们的需求

所以完全不必将软件工程里的东西运用在 ML 上

顺便吐槽一下,如果你去看过一些开源的 ML 项目,解决依赖问题让那些该死的代码在本地跑起来就得费一番功夫。MLer: it runs on my machine ((

类无非就两个功能:

  1. 将不同步骤放在一起,用一个入口函数 main/run 串起来完成一个 pipe ,也可能跳步骤共用数据,其实更多是为了易读和 import 不用写一长串函数名,func_a -> func_b -> func_c ,有个数据可能 a/c 都用到,b 不需要,类内调用无需写成参数传递,会方便些
  2. 复用,类里面的某个或多个方法可以用在不同的项目,或者项目内多模块多次调用,这种方法要写成通用,必要时还要写成抽象类
    例如
    opencv 不支持非英语路径,就可能要写个兼容闭包函数 read/write/resize/rotate/crop 等等,且这个肯定是不同地方会用到的,又如巨型图片要用 pyvips ,还有其他类似包,各家函数方法名还不同,但读写图像常用就是用到路径、尺寸、格式、灰或彩这些设置而已,写个抽象类用相同的函数名和参数全兼容,不用逐个记
    当然,可以 AI 一把梭,也是不用记

其他就没必要写成类或 oop

python 为什么会在机器学习后流行起来,主要原因是调参,每改一个参数就编译一次,一个模型结果不理想换一个又要编译一次……
我昨天跑一个测试看效果,才两个参数,换了三个模型,跑了几十次……如果是换作编译语言的话……还好,我也不会写

你自己做实验的时候,没必要考虑这些东西。你应该关注的算法比如实现新的算子或者是新的结构,而不是纠结与算法的实现。只要你的工作 work 了,就算写出来一坨屎,也会有人前仆后继的帮你重构。

把自己的时间花在值钱的地方。至于 SOLID 什么的,就让臭写代码的来做(或者以后进大厂了再说也来得及)

我个人一般在需要复用的时候才会想到对象。

比如对多示例、继承、多态有刚需的时候,
相似逻辑的代码只想写一遍。

1.不要局限于对象,或者说类;
2.聚焦于接口(要做什么);
3.将你的问题,分解为多个小问题,每个问题都是一个接口(明确输入输出);
4.不太方便标准化的东西(屎),就把他私有化在一个包内部;
5.将处理一类或者一个流程的接口(和屎),聚合在一起(一个包或者一个类),就完成封装了。