如题。本人本身对 Python 语言很喜欢,阅读过《流程的 Python 》、《 Python 工匠》,尝试过钻研一些 Python 的进阶特性,但本人本身是学生,没有任何业务实战经验,只会调一些机器学习、深度学习常用的库,例如 Pandas 、PyTorch 、Transformers 。
一直对面向对象的思想很着迷,了解过 SOLID 原则,平时写代码也会训练自己注意这些,但不熟悉 23 种设计模式,只略有耳闻。平时写代码,喜欢把代码封装成类。但是总觉得自己在“自嗨”,每次把一些代码封装并调试好之后,都有一种失落感,好像自己什么也没干。
感觉很多 Python 的读物,都教了 Python“面向对象”的知识,但我始终不知道,什么时候该用“面向对象”,以及为什么要用“面向对象”。
问题描述的可能不太完整,但希望站内的大佬不吝赐教,感谢!
谢谢各位前辈的指点,因为时间问题,没能及时回复各位,但还是非常谢谢!
个人总结以下大家对我提问题的见解和建议:
大家的一些观点或思想:
可能总结的不完整、不完善。但这些已经让我受益匪浅,不再内耗了。很受益,真的很感谢大家!
1
harlen 15 天前 ![]() 道法自然,多看看 Python 比较流行的库别人是怎么做的,你就会明白,python 想怎么写就怎么写,变量想怎么命名就怎么命名🤔
|
2
harlen 15 天前 ![]() 开个玩笑,认真的, 想学面对对象,就多看看 java 的一些源码,比如 spring 全家桶,
|
3
TimG 15 天前 via Android ![]() 抽象化是软件工程要注意的事。之所以产生专门软件工程的学问就是一个人和一群人写代码要注意的情况是不同的,一百行代码和一万行代码要注意的情况也是不同的。op 觉得封装在“自嗨”,很可能就是目前项目的规模(组内人员数、代码规模)还没有达到必要封装的数量级。
|
4
hwdq0012 15 天前 ![]() oop 还是得看 java , 所有东西都得写个 class
设计思想和设计模式 只是为了让代码更好维护,更好重用,不是为了让代码更容易理解 就是 oop 孔乙己口中的 “高内聚,低耦合” 但是了解这设计模式后,确实是会一下 get 到程序的框架, 就好像看到 foo bar 就知道这个是测试代码 使用一些库或框架,你学了它的用法,就学到设计模式了,它无处不在, 相逢何必曾相似 你且先去模仿罢 |
5
NessajCN 15 天前 ![]() oop 适合给商业公司分锅堆屎山,自己写东西别沾那套
|
![]() |
6
SmiteChow 15 天前
当变量有一组行为的时候就说明它应该用类实现
|
![]() |
7
SmiteChow 15 天前 ![]() 听你的描述,你做的工作其实是调参,一个脚本一个 function 就能解决,自然不需要类,类涉及到领域抽象。
|
8
Hstar 15 天前
写得太少, 看得也少.
首先不用看什么设计模式, 那是基于 Java 特性编的, 你看除了 Java 还有哪些语言天天讲依赖注入来做控制反转的, 我们 Python 直接把函数当参数传过去就做完控制反转了. 然后可以看看优秀的开源库, 比如 requests 这种, 也可以看看大公司开源出来的 sdk 都是这么组织代码的. 最后, 写多了改多了自然就懂了. |
![]() |
9
adoal 15 天前 ![]() 拿编程作为科研工具,自然是没办法学到工程化的技能。得写面向实际使用的业务功能。
|
10
Syiize 15 天前 via Android ![]() 还是写的不够多。我写了快五年 Python 了,没有系统看过这些书,中间尝试过很多风格,最后才按照自己的喜好和习惯慢慢固定到一种风格上。只要你保证写完很长时间以后自己能看懂,就行。
|
![]() |
11
111111111111 15 天前 ![]() 如果你学了软件工程就会知道, 先面向对象分析,然后面向对象设计,最后才是面向对象编程,只知道面向对象编程意义不是很大
如果你掌握多种语言(比如 c++、java 、python )就会知道,不同语言中的面向对象实现是不一样的,一些思想细节也是不一样 至于设计原则、高内聚低耦合这些的前提是代码需要维护、修改、协作,特点是人多、代码多、逻辑复杂、时间跨度大、水平差距大,如果是一个人、少量代码、不需要反复修改,不好体会到好处。所以 具体到 Python 语言,用不用面向对象,和用不用`class` 关系不大,所以他不是一个语法的事情,而是一个思想的事情,如果回到第一句,在分析和设计时用采用面向对象方法,写代码就可以很自然实现面向对象(不论用不用 class 语法) 面向对象、设计模式是前辈根据工程实践提出的方法论,不必刻意追求这些, 代码写多了看多了,有了自己的思路和方法论,就好理解这些别人提出的经典方法论了(当然,你带着这样的疑惑不断思考,也是一种精进) |
12
prosgtsr 15 天前 via iPhone ![]() 多改屎山,这样你才知道什么是 bad smell ,在自己写到时候才会第一时间反应这么写有 bad smell ,应该设计一下
现在你的代码的量应该不需要设计,能用就完了 |
13
henix 15 天前 ![]() 怀疑你可能光看书而缺少实践
自己写点实用的小工具,多写代码(最好是生活中遇到的问题),遇到不知道怎么处理、设计的情况,再去看书 为什么要用面向对象或设计模式,这些都是抽象的方法,但是也并不是所有情况都适用的。个人认为要说有什么代码设计中的核心原则的话,那就是 DRY ( Don't Repeat Yourself ),很多东西都是为了避免重复的,比如多个地方出现的重复的逻辑,就想办法把它们抽象成函数或类。 那为什么要避免重复呢,这是为了方便修改,未来可能出现新的需求,要改的话只改一处地方就好了。 |
![]() |
14
tpeng9240 15 天前
之前写 java 的,现在写 python ,真的也很迷,到底什么时候用对象😂
|
![]() |
15
huangyezhufeng 15 天前 ![]() 一般来说,搞 ML 的代码写的一般都会比较随意(无贬义),因为大部分时候没必要写那么好。根本在于代码主要是为了做实验,不需要长期维护。所以如果想找一些 best practice, 就找哪些非 ML 且长期维护的 Python 库参与贡献比较好。
|
![]() |
16
jiangzhexin 15 天前 ![]() ML 和软件工程没什么共性的,虽然他们都写 python ,但完全是两个东西
结论就是,ML 那帮人只是需要一些写起来简单的让 CPU / GPU 完成运算的“命令” 罢了,python 只是恰好因为语法直观以及胶水的特性满足他们的需求 所以完全不必将软件工程里的东西运用在 ML 上 顺便吐槽一下,如果你去看过一些开源的 ML 项目,解决依赖问题让那些该死的代码在本地跑起来就得费一番功夫。MLer: it runs on my machine (( |
17
NoOneNoBody 15 天前 ![]() 类无非就两个功能:
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 为什么会在机器学习后流行起来,主要原因是调参,每改一个参数就编译一次,一个模型结果不理想换一个又要编译一次…… 我昨天跑一个测试看效果,才两个参数,换了三个模型,跑了几十次……如果是换作编译语言的话……还好,我也不会写 |
![]() |
18
javazero 15 天前 ![]() 你自己做实验的时候,没必要考虑这些东西。你应该关注的算法比如实现新的算子或者是新的结构,而不是纠结与算法的实现。只要你的工作 work 了,就算写出来一坨屎,也会有人前仆后继的帮你重构。
把自己的时间花在值钱的地方。至于 SOLID 什么的,就让臭写代码的来做(或者以后进大厂了再说也来得及) |
![]() |
19
Sawyerhou 14 天前 ![]() 我个人一般在需要复用的时候才会想到对象。
比如对多示例、继承、多态有刚需的时候, 相似逻辑的代码只想写一遍。 |
20
THESDZ 14 天前 ![]() 1.不要局限于对象,或者说类;
2.聚焦于接口(要做什么); 3.将你的问题,分解为多个小问题,每个问题都是一个接口(明确输入输出); 4.不太方便标准化的东西(屎),就把他私有化在一个包内部; 5.将处理一类或者一个流程的接口(和屎),聚合在一起(一个包或者一个类),就完成封装了。 |
21
laike9m 14 天前 ![]() 其实核心就一条:
当你发现某些数据和函数经常需要同时被使用,那就用面向对象。 一个对象说到底就是封装了数据以及数据的操作(方法)的命名空间。 忘掉设计模式,尤其是忘掉继承,因为大多时候你根本不需要继承。 |
![]() |
22
FINCTIVE 14 天前 via Android ![]() 推荐一下《软件设计的哲学》这本书(作者是斯坦福教授、Tcl 语言发明者)。有在线版,很好读,很容易读。
类似这样的问题,不同人有不同的观点。这本书的讨论深度对我真的很有启发。 |
23
visper 14 天前 ![]() 你都已经知道 solid 原则了。剩下就是自己的抽象能力了。其实所有各种设计模式说白了,都是为了一个目标:以后修改代码或者功能的时候,一是尽量少动原来的代码,二是动部分的时候不会影响原来的。 剩下的其实用不用类用不用继承这些,不大重要。有些人觉得用起来很厉害,然后实现一个功能的时候封装了十层八层。到头来别人一看都不知道看在哪里。特别是像 python 这样的动态类型语言,idea 跳转之类的没有 java 这么强的话,保持代码量少更重要一点吧个人感觉。 不要过度设计,不要提前优化。
|
24
visper 14 天前
另外,个人感觉研究 ml 算法这些的学生,应该对函数式编程更感兴趣一点而不是面向对象编程。
|