☰
从 “洗衣服“ 看透面向对象:类和对象到底是个啥,老哥用代码讲到明白
2026/11/3 10:41:33 网站建设 项目流程

前面写的代码都是 "从头到尾一步步执行",这叫面向过程—— 像自己动手洗衣服:脱下来→找盆→放洗衣粉→加水→揉→拧→晾,每一步都自己干。

但真实项目不是这样。老哥用洗衣服再讲一遍:

  • 面向过程:把 "洗衣服" 拆成一堆步骤,逐个写成函数,每一步都自己控制;
  • 面向对象:抽象出 "洗衣机" 这个对象,它有属性(容量、牌子)和方法(洗、烘干)。使用者只管 "扔衣服→按钮→晾起来"。

Python 两种都支持,是混合型语言。而现代大型项目,基本都用面向对象编程(OOP)。

一、类和对象是什么

类(Class)是对大量对象共性的抽象,是创建对象的模板。比如 "学生" 是一个类,共性属性有学号、姓名、年龄,共性方法有学习、跑步、睡觉。

对象(Object)是类的具体实例(Instance)。"101 教室的张三" 是一个具体对象;"我家的这只猫" 也是对象 —— 猫是类,这只猫是实例。

类 = 图纸 / 模板;对象 = 按图纸造出来的实物。类是抽象的,对象是具体的。

二、定义类和创建对象

用class定义类,类名用大驼峰命名法(每个单词首字母大写):

class Person: """人的类""" # 类说明文档 home = "earth" # 类属性(类变量) def __init__(self): # 初始化方法 self.age = 0 # 实例属性 def eat(self): # 实例方法 print("eating...") def drink(self): print("drinking...")

实例化(创建对象):变量名 = 类名()。类支持两种操作:成员引用(类名.成员名)和实例化。

p = Person() # 创建对象(实例化) print(p.home) # earth 访问类属性 print(p.age) # 0 访问实例属性 p.eat() # eating... p.drink() # drinking...

三、__init__()方法和 self

__init__()是初始化方法:对象创建后、返回调用者前自动调用,用来初始化数据。可以传参:

class Person: def __init__(self, name): # 传入 name self.name = name p = Person("张三") print(p.name) # 张三

self 代表实例自身。调用实例方法时,实例会自动作为第一个参数传进去。所以p.eat()就等价于Person.eat(p):

p = Person("张三") p.eat() # eating... Person.eat(p) # 等价写法

在类内部,想访问自己的实例属性、调用自己的方法,都要通过 self:

class Person: def __init__(self, name): self.name = name def eat(self): print("eating...") def eat_and_drink(self): print(self.name) # 类内调用实例属性 self.eat() # 类内调用实例方法

四、类属性 vs 实例属性

类属性:在方法外定义,用类名.属性名访问,所有实例共享一份:

class Person: home = "earth" # 类属性 p1 = Person(); p2 = Person() print(p1.home, p2.home) # earth earth Person.home = "mars" # 改类属性 print(p1.home, p2.home) # mars mars 两个实例都变

实例属性:在方法里用self.属性名定义,每个实例独有一份:

class Person: def __init__(self, name): self.name = name self.age = 0 p1 = Person("张三"); p2 = Person("李四") p1.age = 18 # 只改 p1 的 print(p1.age) # 18 print(p2.age) # 0 p2 不受影响

实例属性也可以在实例化后动态添加:p1.age = 18直接赋值即可。

五、类里的三种方法

1. 实例方法:第一个参数self,只能被实例调用,能访问实例属性:

class Person: def __init__(self, name): self.name = name def instance_method(self): print(self.name) # 访问实例属性 p = Person("张三") p.instance_method()

2. 类方法:用@classmethod装饰,第一个参数cls代表类本身,能被类和实例调用,适合和类整体相关的操作:

class Person: home = "earth" @classmethod def class_method(cls): print(cls.home) # 访问类属性 Person.class_method() # 用类调用 p = Person(); p.class_method() # 用实例调用也行

3. 静态方法:用@staticmethod装饰,不访问类和实例内部,像个工具函数,只是组织在类里:

class Person: @staticmethod def static_method(): print("static method") Person.static_method() p = Person(); p.static_method()

六、魔法方法(特殊方法)

方法名两个下划线开头结尾的是特殊方法,会在特定操作时自动调用:

  • __new__():创建对象时第一个调用的方法;
  • __init__():初始化方法,创建对象后、返回前调用;
  • __del__():对象被垃圾回收时的销毁器;
  • __str__():str()时的行为,给人类看的;
  • __repr__():repr()时的行为,尽量是机器可读、可还原的代码;
  • __getattribute__():属性访问拦截器。

七、动态添加和__slots__限制

Python 很灵活,对象和类都能动态添加属性方法:

class Person: def __init__(self, name=None): self.name = name p = Person("张三") p.age = 18 # 动态给对象添加属性 Person.home = "earth" # 动态给类添加属性 def eat(): print("吃饭") p.eat = eat # 动态给对象添加方法 p.eat() # 吃饭

用__slots__可以限制实例能添加的属性,超出会报错:

class Person: __slots__ = ("name", "age") # 只允许这两个属性 def __init__(self, name=None): self.name = name p = Person("张三") p.age = 10 # 可以 p.weight = 100 # AttributeError!不在 __slots__ 里

注意__slots__只对当前类生效,不影响子类。

老哥收尾

一句话总结这节:

类是模板、对象是实例;__init__初始化、self 指实例;类属性共享、实例属性独有;实例 / 类 / 静态三种方法按需用;魔法方法自动触发;__slots__能锁死属性。

下一篇讲面向对象的三大特性—— 封装、继承、多态,这是 OOP 的灵魂。有问题随时回来找老哥。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询