本文目录导读:

在 Python 中,构造方法(也称为构造函数)是 __init__ 方法,它在创建类的实例时自动调用,主要用于初始化对象的属性。
📌 基本语法和使用
最简单的构造方法
class Person:
def __init__(self, name, age):
self.name = name # 实例属性
self.age = age # 实例属性
# 创建对象时自动调用 __init__
p = Person("小明", 25)
print(p.name) # 输出:小明
print(p.age) # 输出:25
🎯 常见使用场景和案例
1️⃣ 带默认参数的构造方法
class Student:
def __init__(self, name, grade="一年级", score=0):
self.name = name
self.grade = grade
self.score = score
def show_info(self):
print(f"学生:{self.name},{self.grade},成绩:{self.score}")
# 使用默认参数
s1 = Student("小李")
s2 = Student("小王", "三年级")
s3 = Student("小张", "五年级", 95)
s1.show_info() # 学生:小李,一年级,成绩:0
s2.show_info() # 学生:小王,三年级,成绩:0
s3.show_info() # 学生:小张,五年级,成绩:95
2️⃣ 计算属性(处理传入的数据)
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
self.area = width * height # 自动计算面积
self.perimeter = 2 * (width + height) # 自动计算周长
rect = Rectangle(5, 3)
print(f"面积:{rect.area}") # 输出:面积:15
print(f"周长:{rect.perimeter}") # 输出:周长:16
3️⃣ 数据验证和初始化处理
class BankAccount:
def __init__(self, account_no, balance=0):
# 验证账户号码
if not isinstance(account_no, str) or len(account_no) != 10:
raise ValueError("账户号码必须是10位字符串")
# 验证余额
if balance < 0:
raise ValueError("余额不能为负数")
self.account_no = account_no
self.balance = balance
self.transactions = [] # 初始化交易记录
def deposit(self, amount):
self.balance += amount
self.transactions.append(f"存款:+{amount}")
# 正确使用
acc = BankAccount("1234567890", 1000)
print(acc.balance) # 输出:1000
# 错误使用会抛出异常
# acc2 = BankAccount("123", 500) # 抛出 ValueError
4️⃣ 可变默认值的处理(重要!)
class ShoppingCart:
# ❌ 错误方式:不要用可变对象作为默认参数
# def __init__(self, items=[]):
# ✅ 正确方式:使用 None 然后判断
def __init__(self, items=None):
self.items = items if items is not None else []
self.total = 0
def add_item(self, item, price):
self.items.append(item)
self.total += price
# 测试
cart1 = ShoppingCart()
cart1.add_item("苹果", 5)
cart2 = ShoppingCart()
cart2.add_item("香蕉", 3)
print(cart1.items) # 输出:['苹果']
print(cart2.items) # 输出:['香蕉'] (不会受cart1影响)
5️⃣ 类继承中的构造方法
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def speak(self):
pass
class Dog(Animal):
def __init__(self, name, age, breed):
# 调用父类的构造方法
super().__init__(name, age)
self.breed = breed # 子类独有的属性
def speak(self):
return "汪汪!"
class Cat(Animal):
def __init__(self, name, age, color):
# 另一种调用方式
Animal.__init__(self, name, age)
self.color = color
def speak(self):
return "喵喵!"
# 使用
dog = Dog("大黄", 3, "金毛")
cat = Cat("小花", 2, "橘色")
print(f"{dog.name}说:{dog.speak()}") # 大黄说:汪汪!
print(f"{cat.name}说:{cat.speak()}") # 小花说:喵喵!
6️⃣ 单例模式(控制实例化)
class DatabaseConnection:
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self, host=None, port=None):
# 只在第一次实例化时初始化
if not hasattr(self, '_initialized'):
self.host = host
self.port = port
self._initialized = True
self._connect()
def _connect(self):
print(f"连接到数据库 {self.host}:{self.port}")
# 使用 - 确保只有一个数据库连接
db1 = DatabaseConnection("localhost", 3306)
db2 = DatabaseConnection("remote", 5432)
print(db1 is db2) # True(同一个实例)
print(db1.host, db2.host) # localhost localhost(没被覆盖)
💡 重要注意事项
__init__ vs __new__
class Demo:
def __new__(cls, *args, **kwargs):
# 创建对象(先执行)
print("1. __new__ 被调用")
instance = super().__new__(cls)
return instance
def __init__(self, value):
# 初始化对象(后执行)
print("2. __init__ 被调用")
self.value = value
d = Demo(10)
# 输出:
# 1. __new__ 被调用
# 2. __init__ 被调用
构造方法不能返回值(除了None)
class WrongDemo:
def __init__(self):
return "错误" # ❌ TypeError: __init__() should return None
class CorrectDemo:
def __init__(self):
pass # 正确:不显式返回或返回None
| 特性 | 说明 |
|---|---|
| 自动调用 | 创建对象时自动执行 |
| 初始化属性 | 最常用,设置实例的初始状态 |
| 参数传递 | 可以带参数,支持默认值 |
| 返回值 | 必须返回 None |
| 继承 | 子类需要调用父类的 __init__ |
| 执行顺序 | __new__ 先于 __init__ |
最佳实践:
- 使用
__init__进行属性初始化 - 避免在
__init__中做耗时操作 - 合理使用参数验证
- 注意可变默认参数的问题
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播