欢迎光临
我们一直在努力

Python全栈修炼之路 | 第10篇:面向对象编程(上)—— 类与对象

作者:还怪好嘞 发布时间:2026-05-29 难度:⭐⭐⭐⭐ 预计阅读时间:30分钟

前言

面向对象编程(Object-Oriented Programming,OOP)是现代编程的核心范式之一。Python作为一门完全面向对象的语言,从设计之初就深度支持OOP思想。本文将深入讲解Python中类与对象的核心概念,从基础用法到底层实现原理,帮助你真正理解Python的面向对象机制。


一、知识点讲解

1.1 什么是面向对象编程

面向对象编程是一种程序设计思想,它将数据和操作数据的方法组织在一起,形成\”对象\”。与面向过程编程相比,OOP具有以下核心特性:

特性
说明
优势
封装 将数据和方法包装在类中 隐藏实现细节,提高安全性
继承 子类继承父类的属性和方法 代码复用,层次清晰
多态 同一接口,不同实现 灵活扩展,降低耦合

1.2 类的定义与实例化

类是创建对象的蓝图,定义了对象应有的属性和方法:

# 定义一个简单的类
class Dog:
\”\”\”狗类,表示一只狗。\”\”\”

# 类属性:所有实例共享
species = \”Canis familiaris\”

def __init__(self, name, age):
\”\”\”初始化方法(构造器)。

Args:
name: 狗的名字
age: 狗的年龄
\”\”\”
# 实例属性:每个实例独立
self.name = name
self.age = age

def description(self):
\”\”\”返回狗的描述信息。\”\”\”
return f\”{

self.name} is {

self.age} years old\”

def speak(self, sound):
\”\”\”让狗发出声音。\”\”\”
return f\”{

self.name} says: {

sound}\”

# 创建实例(对象)
my_dog = Dog(\”Buddy\”, 3)

# 访问属性和方法
print(my_dog.name) # Buddy
print(my_dog.description()) # Buddy is 3 years old
print(my_dog.speak(\”Woof!\”)) # Buddy says: Woof!

1.3 init 方法详解

__init__是类的构造方法,在创建实例时自动调用:

class Person:
\”\”\”人类。\”\”\”

def __init__(self, name, age=0, email=None):
\”\”\”初始化方法支持默认参数。

Args:
name: 姓名(必需)
age: 年龄(可选,默认0)
email: 邮箱(可选,默认None)
\”\”\”
self.name = name
self.age = age
self.email = email
self._is_active = True # 内部状态

# 可以在初始化时执行其他操作
print(f\”创建了Person对象: {

self.name}\”)

def __del__(self):
\”\”\”析构方法,对象被销毁时调用(不常用)。\”\”\”
print(f\”Person对象 {

self.name} 被销毁\”)

# 不同方式创建实例
p1 = Person(\”Alice\”) # 只提供必需参数
p2 = Person(\”Bob\”, 25) # 提供部分可选参数
p3 = Person(\”Carol\”, 30, \”carol@example.com\”) # 提供所有参数
p4 = Person(\”David\”, email=\”david@test.com\”) # 使用关键字参数

1.4 self 参数的本质

self代表类的实例本身,是Python类方法的第一个参数:

class Example:
def method(self, x):
\”\”\”实例方法,第一个参数是实例本身。\”\”\”
print(f\”self is: {

self}\”)
print(f\”x is: {

x}\”)
return x * 2

# 调用方式1:通过实例调用(推荐)
obj = Example()
result = obj.method(5) # Python自动将obj作为self传入

# 调用方式2:通过类调用(需要手动传入实例)
result = Example.method(obj, 5) # 等价于上面的调用

重要理解:self不是Python关键字,你可以使用其他名称,但强烈建议遵循约定使用self。

1.5 类属性 vs 实例属性

class Counter:
\”\”\”计数器类,演示类属性和实例属性的区别。\”\”\”

# 类属性:所有实例共享
count = 0

def __init__(self):
# 实例属性:每个实例独立
self.instance_count = 0

def increment(self):
\”\”\”增加计数。\”\”\”
Counter.count += 1 # 修改类属性
self.instance_count += 1 # 修改实例属性

@classmethod
def get_class_count(cls):
\”\”\”获取类计数。\”\”\”
return cls.count

# 演示类属性和实例属性的区别
c1 = Counter()
c2 = Counter()

c1.increment()
c1.increment()
c2.increment()

print(f\”c1.instance_count: {

c1.instance_count}\”) # 2
print(f\”c2.instance_count: {

c2.instance_count}\”) # 1
print(f\”Counter.count: {

Counter.count}\”) # 3(两个实例共享)
print(f\”c1.count: {

c1.count}\”) # 3
print(f\”c2.count: {

c2.count}\”) # 3

关键区别:

特性
类属性
实例属性
定义位置 类体中 __init__中
共享性 所有实例共享 每个实例独立
访问方式 ClassName.attr或self.attr self.attr
修改影响 影响所有实例 只影响当前实例

1.6 访问控制与命名修饰

Python没有像Java那样的严格访问控制,但使用命名约定来实现类似效果:

class BankAccount:
\”\”\”银行账户类,演示访问控制。\”\”\”

bank_name = \”Python Bank\” # 公有类属性
_total_accounts = 0 # 保护属性(约定)

def __init__(self, owner, balance=0):
self.owner = owner # 公有属性
self._balance = balance # 保护属性(单下划线)
self.__transaction_log = [] # 私有属性(双下划线)
BankAccount._total_accounts += 1

def deposit(self, amount):
\”\”\”存款(公有方法)。\”\”\”
if amount > 0:
self._balance += amount
self.__log_transaction(f\”Deposit: +{

amount}\”)
return True
return False

def withdraw(self, amount):
\”\”\”取款(公有方法)。\”\”\”
if 0 < amount <= self._balance:
self._balance -= amount
self.__log_transaction(f\”Withdrawal: –{

amount}\”)
return True
return False

def _calculate_interest(self, rate):
\”\”\”计算利息(保护方法)。\”\”\”
return self._balance * rate

def __log_transaction(self, message):
\”\”\”记录交易(私有方法)。\”\”\”
self.__transaction_log.append(message)

def get_balance(self):
\”\”\”获取余额。\”\”\”
return self._balance

def get_transaction_log(self):
\”\”\”获取交易记录(受控访问)。\”\”\”
return self.__transaction_log.copy()

# 访问控制演示
account = BankAccount(\”Alice\”, 1000)

# 公有属性和方法 – 正常访问
print(account.owner) # Alice
account.deposit(500)

# 保护属性 – 可以访问但不建议
print(account._balance) # 1500(但不应该直接访问)

# 私有属性 – 名称修饰后访问
# print(account.__transaction_log) # AttributeError
print(account._BankAccount__transaction_log) # 可以访问但不推荐

# 查看名称修饰
print(dir(account)) # 可以看到 _BankAccount__transaction_log

命名修饰(Name Mangling)机制:

  • 双下划线开头的属性会被改名为 _ClassName__attribute
  • 这是为了防止子类意外覆盖父类的私有属性
  • 不是真正的私有化,只是约定和机制的结合

二、底层原理

2.1 type、object、class的三角关系

Python中的一切都是对象,理解type、object和class的关系是掌握Python面向对象的关键:

# 探索Python的对象模型
class MyClass:
pass

obj = MyClass()

# 1. 对象的类型
print(type(obj)) # <class \’__main__.MyClass\’>
print(type(MyClass)) # <class \’type\’>
print(type(type)) # <class \’type\’> type是它自己的类型

# 2. 类的基类
print(MyClass.__bases__) # (<class \’object\’>,)
print(type.__bases__) # (<class \’object\’>,)
print(object.__bases__) # () object是所有类的基类

# 3. 对象的关系
print(isinstance(obj, MyClass)) # True
print(isinstance(obj, object)) # True
print(issubclass(MyClass, object)) # True
print(issubclass(type, object)) # True

# 4. 关键结论
print(type(object)) # <class \’type\’> object是type的实例
print(isinstance(type, type)) # True type是它自己的实例

核心关系图:

┌─────────────────────────────────────────────────────────┐
│ object │
│ (所有类的基类) │
│ ┌─────────────────────────────────────────────────┐ │
│ │ type │ │
│ │ (所有类的类型,包括它自己) │ │
│ │ ┌─────────────────────────────────────────┐ │ │
│ │ │ MyClass │ │ │
│ │ │ (用户定义的类,type的实例) │ │ │
│ │ │ ┌─────────────────────────────────┐ │ │ │
│ │ │ │ obj │ │ │ │
│ │ │ │ (MyClass的实例) │ │ │ │
│ │ │ └─────────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘

核心规则:

  • type是自身的实例(type(type) is type)
  • object是type的实例(type(object) is type)
  • type继承自object(
  • 赞(0)
    未经允许不得转载:171主机测评 » Python全栈修炼之路 | 第10篇:面向对象编程(上)—— 类与对象
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址