为什么我不再盲目使用 Python 类了?
刚开始学 Python 的时候,我跟大多数人一样,觉得“面向对象”就是高级。写点逻辑也非得包到类里,动不动就来个 class,好像不用类就不算会写 Python。后来工作几年,踩过坑,写过一堆冗余代码,再回过头来看,才发现很多时候我压根不需要类。
类并不是银弹
类的好处大家都懂:封装、继承、多态。但问题是,在 Python 里,类并不是必须的。很多场景下,函数和模块就能解决问题。尤其是 Python 语言本身就提供了字典、函数式编程特性、数据类(dataclasses)、命名元组(namedtuple),这些都可以代替类去承载数据或者逻辑。
比如,我当时写个配置加载器,非要写成这样:
classConfigLoader:
def__init__(self, path):
self.path = path
defload(self):
with open(self.path, "r") as f:
return f.read().splitlines()loader = ConfigLoader("config.txt")
configs = loader.load()
结果呢,这玩意儿一辈子只用一次,写个函数完全足够:
defload_config(path: str):
with open(path, "r") as f:
return f.read().splitlines()configs = load_config("config.txt")
可读性更好,调用也更直观,根本没必要套个壳。
数据类才是“轻量级类”
很多人用类只是为了存数据。比如:
classUser:
def__init__(self, name, age):
self.name = name
self.age = age
Python 里完全可以用 dataclasses,既省事又自带好用的 __repr__、__eq__ 方法。
from dataclasses import dataclass@dataclass
classUser:
name: str
age: int
写法清爽多了,调试的时候打印对象也更直观。
甚至在更轻量的场景下,用 namedtuple 就足够:
from collections import namedtupleUser = namedtuple("User", ["name", "age"])
u = User("Alice", 30)
print(u.name)
类滥用的几个坑
过度封装有些逻辑本来就只是一小段业务,偏要抽象成各种方法和属性,结果别人读起来要来回翻。最后维护的人骂的不是代码,而是你。
继承陷阱Python 的多继承是有用,但多数时候会搞得逻辑复杂,还引出菱形继承、方法解析顺序(MRO)这些问题。维护成本比你省下的那点代码多得多。
性能损耗在一些热点逻辑里,不必要的类和对象创建会拖慢速度。比如在循环里频繁 new 对象,有时用字典就能解决。
# 类的写法
classPoint:
def__init__(self, x, y):
self.x = x
self.y = ypoints = [Point(x, x*2) for x in range(1000000)]
# 字典的写法
points = [{"x": x, "y": x*2} for x in range(1000000)]
大多数情况下,用字典会更快,也更省内存。
那什么时候该用类?
并不是说类没用。在以下场景,用类是合适的:
状态需要长期维护(比如一个连接池对象)。 明确需要多态(比如不同支付方式继承同一个 PayMethod)。框架约定(Django 的 Model、Flask 的视图类,这些不能绕)。
但除此之外,不要为了“面向对象”而面向对象。
我现在写代码的习惯是:能用函数解决,就用函数;能用数据结构解决,就用数据结构;实在需要状态和抽象,才用类。这样代码更短、更直观,后面接手的人也不至于被“类森林”绕晕。
类是工具,不是枷锁。别被一开始的“高级感”骗了。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领