首页 / Python3 入门教程 / 面向对象基础

Python3 入门教程

面向对象基础

本教程共 70 篇 · 第 31 篇 · 更新于 2026-07-22 · 约 5 分钟阅读

PythonPython3 入门教程面向对象类与对象__init__self

31. 面向对象基础

本节目标:理解「类」和「对象」的区别,学会用 class 定义类,用 __init__ 初始化实例,搞懂 self 到底是什么。

前面我们写的代码都是面向过程(procedure-oriented)的:把问题拆成一个个函数,按顺序调用。这种写法在小项目里没问题,但代码一多,数据和函数散落在各处,维护起来很头疼。

面向对象编程(Object-Oriented Programming,简称 OOP)换了一种思路:把数据和操作数据的方法打包在一起,形成一个「类(class)」。类就像一张设计图纸,而根据图纸造出来的东西叫「实例(instance)」或「对象(object)」。

从一个例子感受 OOP

假设你要管理学生信息。面向过程的写法可能是这样的:

stu1 = {'name': '张三', 'score': 85}
stu2 = {'name': '李四', 'score': 92}

def print_score(stu):
    print(f"{stu['name']}: {stu['score']}")

print_score(stu1)

数据是字典,操作数据的函数单独定义。如果字段多了、逻辑复杂了,这种写法会越来越乱。

用面向对象改写:

class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def print_score(self):
        print(f"{self.name}: {self.score}")

stu1 = Student('张三', 85)
stu2 = Student('李四', 92)

stu1.print_score()
stu2.print_score()

namescore 跟操作它们的方法绑在了一起。逻辑清晰,扩展也方便。

定义类和创建实例

在 Python 里,用 class 关键字定义类:

class Dog:
    pass

d = Dog()
print(type(d))  # <class '__main__.Dog'>

类名通常用大驼峰命名法(CamelCase),比如 StudentInfoHttpRequest

init 方法:初始化实例

类里可以定义一个特殊方法 __init__,它在创建实例时自动执行,用来给实例设置初始状态:

class Cat:
    def __init__(self, name, age):
        self.name = name
        self.age = age

c = Cat('咪咪', 2)
print(c.name)  # 咪咪
print(c.age)   # 2

__init__ 的第一个参数固定叫 self,代表实例本身。后面跟的参数,在创建实例时传入。

Note

__init__ 方法返回 None,不能显式写 return 其他值。你只管在里面给实例绑定属性就好。

self 是什么

self 这个单词不是关键字,你可以改成别的名字,但全世界都用 self,你也跟着用。

它代表「当前实例」。当你调用 stu1.print_score() 时,Python 在背后做了这件事:Student.print_score(stu1)。也就是说,实例方法会自动把调用者当成第一个参数传进去。

class Demo:
    def show(self):
        print(f"self 的 id: {id(self)}")

d = Demo()
print(f"d 的 id:    {id(d)}")
d.show()

运行后你会发现两个 id 完全一样。这就是 self 的本质:它就是实例自己。

实例属性和方法

绑定属性

属性可以动态绑定,不限于 __init__ 里定义的那些:

class Book:
    def __init__(self, title):
        self.title = title

b = Book('Python 入门')
b.price = 39.9       # 动态绑定新属性
print(b.price)       # 39.9
Warning

动态绑定属性很灵活,但也会让代码变得难以追踪。建议把实例该有的属性都在 __init__ 里声明,方便别人阅读。

定义方法

类里的函数叫「方法(method)」。第一个参数必须是 self,这样它才能访问实例的属性:

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

    def perimeter(self):
        return 2 * (self.width + self.height)

r = Rectangle(3, 4)
print(r.area())       # 12
print(r.perimeter())  # 14

方法内部通过 self.widthself.height 读写实例属性。

类属性 vs 实例属性

类属性是定义在类体里、不在任何方法内的变量。它属于类本身,所有实例共享同一份:

class Dog:
    kind = 'canine'  # 类属性

    def __init__(self, name):
        self.name = name  # 实例属性

d1 = Dog('旺财')
d2 = Dog('来福')

print(d1.kind)  # canine
print(d2.kind)  # canine
print(d1.name)  # 旺财
print(d2.name)  # 来福

如果通过实例去修改类属性,Python 会给这个实例新建一个同名的实例属性,并不会影响类本身:

d1.kind = 'husky'
print(d1.kind)   # husky(实例属性)
print(d2.kind)   # canine(类属性没变)
print(Dog.kind)  # canine
Tip

类属性适合放「所有实例都一样」的数据,比如计数器、常量配置。实例属性放「每个实例各自不同」的数据。

给类加计数器

一个类属性的经典用法:统计一共创建了多少个实例。

class User:
    count = 0

    def __init__(self, name):
        self.name = name
        User.count += 1

u1 = User('Alice')
u2 = User('Bob')
print(User.count)  # 2

注意这里用 User.count += 1,不是 self.count += 1。如果用后者,会变成给实例绑定新属性,计数就失效了。

小结

  • 类是模板,实例是根据模板创建的对象。
  • __init__ 在实例创建时自动执行,用来初始化属性。
  • self 代表实例本身,是实例方法的第一个参数。
  • 实例属性每个对象独立;类属性所有对象共享。

你可以把类想象成一个模具厂。class 是模具的设计图,__init__ 是每次开模时的初始化操作,self 就是流水线上当前那块正在加工的材料。


来源:参考了 runoob「Python3 面向对象」、liaoxuefeng「面向对象编程」和「类和实例」、pythondoc「9. 类」等,改写后所得。