Python 面向对象基础:从类到实例,再到方法与属性
Python 面向对象基础:从类到实例,再到方法与属性
在 Python 中,面向对象编程(OOP)是一种重要的编程范式,它通过“类”和“对象”来组织代码,使程序更易于扩展和维护。本文将带你从零开始理解 Python 中的类、对象、属性以及各种方法,并通过大量代码示例巩固概念。
1. 类与对象:蓝图与实体
1.1 什么是类?
类 是创建对象的蓝图或模板。它定义了一组属性和方法,描述了对象“长什么样”以及“能做什么”。在 Python 中使用 class 关键字定义类。
class Dog:
pass # 一个空类
1.2 什么是对象?
对象 是根据类创建出来的具体实体。同一个类可以实例化出多个对象,每个对象拥有自己的数据(实例属性),但共享相同的行为(方法)。
class Dog:
def bark(self):
print("Woof!")
# 创建对象(实例化)
my_dog = Dog()
my_dog.bark() # 输出: Woof!
创建对象的语法是 类名(),这个过程称为实例化。
1.3 类本身也是对象
在 Python 中,类本身也是一个对象,它属于 type 类型。这意味着你可以像操作普通对象一样操作类:将其赋值给变量、作为函数参数等。
class Car:
pass
print(type(Car)) # <class 'type'>
print(isinstance(Car, type)) # True
2. 属性:描述对象的状态
属性分为类属性和实例属性,它们的作用域和生命周期不同。
2.1 实例属性(属于具体对象)
实例属性是绑定到每个具体对象上的数据,不同对象的实例属性互不影响。通常在 __init__ 方法中通过 self.属性名 = 值 来定义。
class Student:
def __init__(self, name, score):
self.name = name # 实例属性
self.score = score
s1 = Student("Alice", 95)
s2 = Student("Bob", 87)
print(s1.name, s1.score) # Alice 95
print(s2.name, s2.score) # Bob 87
2.2 类属性(属于类对象)
类属性直接定义在类内部,所有实例共享同一个类属性。可以通过 类名.属性名 或 实例.属性名 访问,但推荐使用类名访问以避免歧义。
class Teacher:
school = "第一中学" # 类属性
def __init__(self, name):
self.name = name
t1 = Teacher("张老师")
t2 = Teacher("李老师")
print(t1.school) # 第一中学
print(t2.school) # 第一中学
# 修改类属性会影响所有实例(通过类名修改)
Teacher.school = "第二中学"
print(t1.school) # 第二中学
print(t2.school) # 第二中学
注意:如果通过实例对类属性赋值,并不会修改类属性,而是为该实例动态创建了一个同名的实例属性,这会遮蔽类属性。
3. 方法:定义对象的行为
在类中定义的函数称为方法。根据第一个参数和装饰器的不同,分为实例方法、类方法和静态方法。
3.1 实例方法
最常见的类型,第一个参数为 self,指向调用该方法的实例。实例方法可以访问实例属性和类属性。
class Counter:
count = 0 # 类属性,记录实例个数
def __init__(self):
Counter.count += 1
self.id = Counter.count
def show_id(self): # 实例方法
print(f"我是第 {self.id} 个实例")
c1 = Counter()
c2 = Counter()
c1.show_id() # 我是第 1 个实例
c2.show_id() # 我是第 2 个实例
3.2 类方法
使用 @classmethod 装饰器,第一个参数为 cls,指向类本身。类方法可以访问和修改类属性,但不能直接访问实例属性。常用于工厂模式或操作类级别的数据。
class Person:
species = "Human"
def __init__(self, name):
self.name = name
@classmethod
def change_species(cls, new_species):
cls.species = new_species
@classmethod
def from_string(cls, data_str):
"""工厂方法:根据字符串创建实例"""
name = data_str.split("-")[0]
return cls(name)
# 使用类方法修改类属性
Person.change_species("Homo sapiens")
print(Person.species) # Homo sapiens
# 类方法作为工厂
p = Person.from_string("Alice-25")
print(p.name) # Alice
3.3 静态方法
使用 @staticmethod 装饰器,没有 self 或 cls 参数。它本质上是一个放在类命名空间里的普通函数,与类和实例的状态无关。适合存放一些工具函数。
class MathUtils:
@staticmethod
def add(x, y):
return x + y
@staticmethod
def is_even(num):
return num % 2 == 0
# 直接通过类名调用
print(MathUtils.add(3, 5)) # 8
print(MathUtils.is_even(10)) # True
4. 构造与初始化:__init__ 方法
很多教程称 __init__ 为构造函数,但严格来说它不是构造函数。真正的对象创建由 __new__ 方法完成,__init__ 只是在对象创建之后对其进行初始化。
__new__:静态方法,负责分配内存并返回一个对象实例。__init__:实例方法,负责设置实例的初始状态(给实例属性赋值)。
我们平时几乎不需要重写 __new__,但需要知道这个区别。
class Example:
def __new__(cls, *args, **kwargs):
print("1. __new__ 被调用,创建对象")
instance = super().__new__(cls)
return instance
def __init__(self, value):
print("2. __init__ 被调用,初始化对象")
self.value = value
e = Example(10)
# 输出:
# 1. __new__ 被调用,创建对象
# 2. __init__ 被调用,初始化对象
5. 综合对比表格
| 类型 | 第一个参数 | 装饰器 | 访问实例属性 | 访问类属性 | 典型用途 |
|---|---|---|---|---|---|
| 实例方法 | self |
无 | ✅ | ✅ | 操作实例数据 |
| 类方法 | cls |
@classmethod |
❌ | ✅ | 操作类属性、工厂方法 |
| 静态方法 | 无 | @staticmethod |
❌ | ❌ | 工具函数,逻辑上属于类 |
6. 小结
- 类是蓝图,对象是根据蓝图创建的实体;类本身也是
type类型的对象。 - 实例属性属于具体对象,在
__init__中通过self定义;类属性属于类本身,所有实例共享。 - 实例方法可以操作实例和类的数据;类方法可以操作类数据,常用于工厂模式;静态方法是独立工具函数。
__init__是初始化方法而非真正的构造函数,真正的构造由__new__完成。
掌握这些基础概念之后,你就可以用面向对象的方式组织 Python 程序了。下一阶段可以学习继承、多态、以及更高级的魔法方法。希望本文对你的学习有所帮助!
更多推荐



所有评论(0)