编译 | 弯月   责编 | 张文

出品 | CSDN(ID:CSDNnews)

许多人都在抨击面向对象,虽然我不认为他有什么问题,但我觉得至少在 Python 中没必要。

近来,许多人都在抨击面向对象,虽然我不认为面向对象本身有什么问题,但我觉得至少在 Python 中没这个必要。

1、没有必要使用面向对象

举个例子,比如下面的代码完全没有必要使用面向对象。

class ApiClient:def __init__(self, root_url: str, session_cls: sessionmaker):self.root_url = root_urlself.session_cls = session_clsdef construct_url(self, entity: str) -> str:returnf"{self.root_url}/v1/{entity}"def get_items(self,entity: str) -> List[Item]:resp = requests.get(self.construct_url(entity))resp.raise_for_status()return [Item(**n) for n in resp.json()["items"]]def save_items(self, entity: str) -> None:with scoped_session(self.session_cls)as session:session.add(self.get_items(entity)) class ClientA(ApiClient):def construct_url(self, entity: str) -> str:returnf"{self.root_url}/{entity}" class ClientB(ApiClient):def construct_url(self, entity: str) -> str:returnf"{self.root_url}/a/special/place/{entity}"client_a = ClientA("https://client-a",session_cls)
client_a.save_items("bars")

这里使用了面向对象,因为我们想把 root_url 绑定到某个对象上,而且不想每次都传递 sessionmaker。我们还想使用继承,在调用的中途访问一个方法。

但如果只通过数据传递和函数能实现吗?

@dataclass
class Client:root_url: strurl_layout: strclient_a = Client(root_url="https://client-a",url_layout="{root_url}/{entity}",
)client_b = Client(root_url="https://client-b",url_layout="{root_url}/a/special/place/{entity}",
)def construct_url(client: Client, entity: str) -> str:returnclient.url_layout.format(root_url=client.root_url, entity=entity)def get_items(client: Client, entity: str) -> List[Item]:resp = requests.get(construct_url(client, entity))resp.raise_for_status()return [Item(**n) for n in resp.json()["items"]]def save_items(client: Client, session_cls: session_cls, entity: str) -> None:withscoped_session(session_cls) as session:session.add(get_items(client, entity))save_items(client_a,session_cls, "bars")

我们必须随时传递 Client 和 session_cls。

但有什么关系呢?代码量甚至还少了 10%。这样编写的代码很容易理解,而且不需要使用面向对象。

有人管这种写法叫做“函数袋”。就是说,整个代码都由有类型的数据和一大堆模块作用域的函数组成。

那么全局变量怎么处理?你可以参考这篇文章(https://leontrolski.github.io/sane-config.html),在整个应用程序的生命周期内重用 config 或 db 的 session,

接口、抽象类怎么办?实际上你不需要它们,直接写代码就行了。平心而论,Python 有了类型标注之后,函数袋风格才开始发挥真正的魅力。

不纯粹的函数怎么办?

如果你想采用纯粹的函数式编程,你可能想编写纯粹的类,然后使用不纯粹的“适配器”实例来做一些处理:getting-the-current-datetime/API-calls/talking-to-the-db/other-impure-stuff。这个想法很不错。实际上你可以直接使用 freezegun、responses 等方法来避免大量麻烦。

2、例外

但也有一些例外的情况:

  • 你可能注意到,重构的代码中加入了@dataclass,它们只是记录类型。Python 5 可以直接支持这些,不需要使用“常规”类。

  • 使用 Exception 的子类是没问题的。使用 try: ... except SomeClass: ...,基本上会形成一种层级,不过没关系,只要不要搞得过于复杂。

  • Enum,与上面一样,它们非常适合 Python。

  • 在极罕见的情况下(至少在应用程序的开发中很少遇到),你可能会想出一种非常好用的类型然后到处使用,就像pandas.DataFrame/sqlalchemy.Session 一样。但是一般情况下,不要自欺欺人,不要骗自己说我们正在构建了不起的应用程序。谦虚使人进步。

3、面向对象的弊端

虽然在本文开头,我说过我不认为面向对象本身有什么问题,但实际上我还是觉得面向对象不仅没有帮助性,而且还常常混淆问题,鼓励一些不良做法:

  • 面向对象鼓励你修改数据。函数袋非常反对修改参数。不相信的话,你可以试试看,但可千万别生气。

  • 面向对象只是返回的全局变量。你无法在函数之间共享数据,self 会强迫你使用更小的状态空间编写方便测试的函数。

  • 混合数据和函数会加剧序列化的难度,而在当今 REST API 流行的情况下,序列化非常有用。

  • 面向对象带来了疯狂的继承体系,关于这个话题的讨论到处都是。

  • 最重要的是,面向对象没有任何附加价值,它只会导致你无法专心解决问题,并加剧浏览与理解代码的难度。

参考链接:https://leontrolski.github.io/mostly-pointless.html

推荐阅读误执行了rm -fr /*之后,除了跑路还能怎么办?!
程序员必备58个网站汇总
大幅提高生产力:你需要了解的十大Jupyter Lab插件

Python 中的面向对象没有意义相关推荐

  1. python采用面向对象编程模式吗_如何理解 Python 中的面向对象编程?

    现如今面向对象编程的使用非常广泛,本文我们就来探讨一下Python中的面向对象编程. 作者 | Radek Fabisiak 译者 | 弯月,责编 | 郭芮 以下为译文: Python支持多种类型的编 ...

  2. python如何初始化对象数组_如何理解Python中的面向对象编程?

    (由Python大本营付费下载自视觉中国) 作者 | Radek Fabisiak 译者 | 弯月,责编 | 郭芮 出品 | CSDN(ID:CSDNnews) 现如今面向对象编程的使用非常广泛,本文 ...

  3. 如何理解 Python 中的面向对象编程?

    现如今面向对象编程的使用非常广泛,本文我们就来探讨一下Python中的面向对象编程. 作者 | Radek Fabisiak 译者 | 弯月,责编 | 郭芮 出品 | CSDN(ID:CSDNnews ...

  4. python面向对象有什么用_Python 中的面向对象没有意义

    许多人都在抨击面向对象,虽然我不认为他有什么问题,但我觉得至少在Python 中没必要. 近来,许多人都在抨击面向对象,虽然我不认为面向对象本身有什么问题,但我觉得至少在 Python 中没这个必要. ...

  5. python中面向对象的缺点_面向对象中的多态在 Python 中是否没有什么意义?

    谢邀! 话说,你为什么说Python中没有数据类型的概念.Python肯定是有数据类型的,在我所见的所有语言中,没有一门编程语言是没有数据类型的. 依据你的问题,我理解或许你的意思是,Python没有 ...

  6. 深入理解Python中的面向对象

    博客核心内容: 面向过程与面向对象的对比 id.type和value的讲解 类和对象的概念 初始化构造函数__init__的作用 self关键字的使用 继承的概念 组合的概念 接口的概念 抽象类的概念 ...

  7. 如何理解Python中的面向对象

    一.认识面向对象是什么 面向过程的程序设计的核心就是过程,就是流水线式的思维,过程就是解决问题的步骤,面向过程的设计就好像一条设计好的流水线,考虑周全什么就处理什么东西. 优点在于极大地降低了写程序的 ...

  8. 第十二篇:python中的面向对象

    编程范式 编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程,一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所谓条条大路通罗马,实现一个任务的方式有很多种 ...

  9. 简述python中面向对象的概念_简述Python中的面向对象编程的概念

    面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程序设计把计算机 ...

最新文章

  1. OPenCv java 形态学操作(12)
  2. python中的open函数实例_Python中open函数注意点
  3. asp.net mvc下的多语言方案 包含Html,Javascript和图片
  4. hibernate 基础学习
  5. Java使用InetAddress类获取主机名和IP地址
  6. 5G:关键技术实现可引领
  7. 数据科学 IPython 笔记本 7.4 Pandas 对象介绍
  8. python thread 多线程
  9. 自己本地如何玩redis_如何把win10系统本地磁盘图标更改为自己的照片
  10. ARM指令集发展概述
  11. WinRAR 激活码(KEY)
  12. 【2022】字节跳动面试真题,1000问(Java岗)
  13. MyBatis学习(一)-- 实现简单查询
  14. 【大学总结】迟到但未缺席的大学总结
  15. CSAPP ArchLab
  16. Python中字符串前“b”,“r”,“u”,“f”的作用
  17. 几种常用方法教你解决QQ空间无法打开问题
  18. Google Earth Engine(GEE)——快速建立一个10km的格网
  19. 霍常亮app淘宝客开发视频教程第7节
  20. 携手 诺基亚N78 共同参与 连城诀

热门文章

  1. SublimeText3: ImportError: No module named ‘urllib2′
  2. Laravel新建对象的方法:make resolve 辅助函数app()
  3. PHP的统一换行PHP_EOL
  4. Yii的Where条件
  5. html教程自适应,Html-自适应
  6. main java game,playgame 一个JAVA编写的飞行小游戏,有基本完整的 框架,适合初学者参照学习 Other s 其他 238万源代码下载- www.pudn.com...
  7. 八代i7装服务器系统2012,八代I7能装win7系统吗,会影响性能吗-8代win7,8代cpu完美装win7...
  8. 编辑函数求n阶乘fact_n!函数用C语言其实可以这样!
  9. rabbitmq连接java快速入门
  10. rp软件app流程图_Axure RP 9 for Mac交互原型设计软件