1135 字
6 分钟
充分了解Python面向对象
2026-03-02
- 实例方法必须带第一个参数, self 只是约定俗成
在 Python 类中定义普通实例方法,第一个参数必须存在,它代表当前调用方法的实例对象本身。
self 不是关键字,只是行业约定的名字,你写成 this 、 me 、 obj 都可以正常运行,只是大家统一用 self ,可读性更高。
当我们用实例调用方法时,Python 会自动把实例对象传给第一个参数,不需要我们手动传递。这个参数的作用,就是让方法能访问、修改当前实例的属性和方法。
- 属性查找顺序:实例优先于类,实例赋值会覆盖类属性
Python 在查找属性或方法时,有一个固定顺序: 先找实例自己的空间 → 找不到,再去类里面找。
这意味着:如果你给实例单独定义了一个变量,类里面的同名属性就不会生效,实例会优先使用自己赋值的内容。
简单例子:
class Dog: name = "小狗"
dog = Dog()# 给实例自己赋值dog.name = "旺财"# 优先用实例自己的,类里的被覆盖print(dog.name) # 输出:旺财```
3. 方法本质是变量,可被动态覆盖
Python 里有一个非常重要的特性:类中的方法,本质上就是类的属性变量。
它和普通变量没有区别,可以直接重新赋值。一旦赋值,原来的方法就会失效,不再能调用,只会变成你赋的值。
极简例子:
```python
class Dog: def bark(self): print("汪汪")
dog = Dog()# 直接把方法覆盖成数字dog.bark = 123# 现在 bark 不是方法,是 123print(dog.bark) # 输出:123```
甚至 Python 内置函数(如 max )也一样,赋值后原功能直接失效。
4. 通过 self.属性 可直接访问、打印当前实例数据
在类的实例方法内部,我们可以直接使用 self.属性名 的格式,获取、打印、修改当前实例自己的数据。
比如 self.name 、 self.age ,不需要依赖外部变量,就能直接拿到当前对象的状态,这是面向对象封装特性最直观的体现。
5. __init__ 构造函数:初始化实例,支持必填参数与默认值
__init__ 是 Python 类的构造函数,在创建实例时会自动执行,不需要手动调用。
它的核心作用:给新创建的实例提前初始化属性,保证后续方法能正常运行,不会因为属性不存在而报错。
使用规则非常简单:
- 如果 __init__ 括号里写了参数(除 self 外)→ 创建实例时必须传入,必填- 如果不在括号传参,直接在方法内部给属性赋值 → 使用固定默认值
例子:
```python
class Dog: def __init__(self): # 内部直接给默认值,创建实例不用传参 self.name = "小狗"
def bark(self): print(f"{self.name} 汪汪叫")
dog = Dog()dog.bark() # 输出:小狗 汪汪叫```
6. Python 一切皆对象:所有数据都是类实例化而来
Python 最经典的设计哲学:一切皆对象。
不管是列表、字符串、数字,还是函数,本质上都是某个类的实例。我们平时使用的 list() 、 str() ,其实都是在调用类的构造方法,把数据传进去,实例化出一个对象。
比如:
```python
# 把元组传给 list 类,实例化成列表对象lst = list((1, 2, 3))# 把数字传给 str 类,实例化成字符串对象s = str(123)它们不是什么特殊类型,就是标准的对象。
- 所有类默认继承 object ,括号里写的是父类
类名后面的括号是干嘛的?是不是参数?
实际上括号里不是参数,是要继承的父类。
在 Python 3 中,有一个终极规则:
- 如果你不写括号,比如 class Dog: → 默认自动继承顶层基类 object
- 如果你写了括号,比如 class Dog(Animal): → 代表 Dog 继承 Animal
- 任何不写父类的类,最终都会继承 object
object 是 Python 所有类的“老祖宗”。
总结
1. self 是约定俗成,代表当前实例 2. 实例属性优先于类属性 3. 方法是变量,可被覆盖 4. self.属性 直接操作实例数据 5. init 初始化,支持必填与默认值 6. 一切皆对象,都是类的实例 7. 类默认继承 object ,括号声明父类
充分了解Python面向对象
https://fuwari.vercel.app/posts/充分了解python面向对象/