init 构造方法
__init__ 是 Python 类中最特殊的方法之一。它在实例创建后自动调用,用于初始化实例的属性。虽然名字里有 "init",但它不是构造函数(对象已经创建好了),而是初始化方法。
基本用法
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("Alice", 25)
print p.name # Alice
print p.age # 25
__init__ 的第一个参数是 self(指向新创建的实例),后面可以跟任意数量的参数。创建实例时,Person("Alice", 25) 的参数会传递给 __init__。
self 参数
self 是实例本身的引用,必须作为第一个参数显式声明:
class Counter(object):
def __init__(self):
self.count = 0 # 给实例添加 count 属性
def increment(self):
self.count += 1 # 通过 self 访问实例属性
return self.count
c = Counter()
print c.increment() # 1
print c.increment() # 2
调用 c.increment() 时,Python 自动把 c 作为第一个参数传给 self。所以 self.count 就是 c.count。
self 不是关键字,可以用其他名字,但强烈建议用 self——这是 Python 社区的约定,违反它会让代码难以阅读。
默认参数
__init__ 可以像普通函数一样使用默认参数:
class Person(object):
def __init__(self, name, age=0, city="Unknown"):
self.name = name
self.age = age
self.city = city
p1 = Person("Alice")
print p1.age, p1.city # 0 Unknown
p2 = Person("Bob", 30, "Beijing")
print p2.age, p2.city # 30 Beijing
p3 = Person("Charlie", city="Shanghai")
print p3.age, p3.city # 0 Shanghai
参数验证
__init__ 中可以进行参数验证,确保对象创建时处于有效状态:
class Rectangle(object):
def __init__(self, width, height):
if width <= 0 or height <= 0:
raise ValueError("Width and height must be positive")
self.width = width
self.height = height
self.area = width * height
r = Rectangle(5, 3)
print r.area # 15
r2 = Rectangle(-1, 3) # ValueError: Width and height must be positive
没有 init 的类
如果类没有定义 __init__,实例创建后没有任何属性:
class Empty(object):
pass
e = Empty()
print e.__dict__ # {},空字典
实例的属性存储在 __dict__ 字典中。__init__ 的作用就是往这个字典里添加初始值。
init 的返回值
__init__ 必须返回 None(隐式或显式)。如果返回其他值,会抛出 TypeError:
class Bad(object):
def __init__(self):
return 42 # TypeError: __init__() should return None
实际应用
银行账户:
class BankAccount(object):
def __init__(self, owner, balance=0):
self.owner = owner
self.balance = balance
self.transactions = []
def deposit(self, amount):
self.balance += amount
self.transactions.append(("deposit", amount))
def withdraw(self, amount):
if amount > self.balance:
raise ValueError("Insufficient funds")
self.balance -= amount
self.transactions.append(("withdraw", amount))
account = BankAccount("Alice", 100)
account.deposit(50)
account.withdraw(30)
print account.balance # 120
配置对象:
class Config(object):
def __init__(self, **kwargs):
self.debug = kwargs.get("debug", False)
self.host = kwargs.get("host", "localhost")
self.port = kwargs.get("port", 8080)
config = Config(debug=True, port=3000)
print config.debug # True
print config.host # localhost
print config.port # 3000