面向对象
定义与创建类
class Dog:
"""一个简单的 Dog 类"""
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(f"{self.name} says Woof!")
# 创建实例 (实例化)
my_dog = Dog("Buddy", 3)
__init__
方法(构造函数)
作用:在创建对象时自动调用,用于初始化对象的属性。
参数:
self
:指向创建的实例本身,是方法的第一个参数(约定俗成,可重命名但不推荐)其他参数:用于接收创建实例时传入的值。
注意:不要返回非
None
的值(除非是__new__
),否则会引发TypeError
。
类的属性和方法
实例属性 & 类属性
实例属性:属于对象,每个对象单独维护一份。
类属性:属于类,所有对象共享。
class Person:
species = "Human" # 类属性
def __init__(self, name):
self.name = name # 实例属性
方法分类
实例方法
class Example:
count = 0
def instance_method(self): # 实例方法
return "instance method", self
类方法(Class Methods)
使用@classmethod
装饰器定义,第一个参数是cls
,指向类本身(而非实例)。不能访问实例守护星,可以访问类属性。长用于创建替代的构造函数(工厂方法)。
class Person:
species = "Homo sapiens"
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def form_string(cls, person_str):
name, age = person_str.split("-")
return cls(name, int(age)) # clas 指向 Person
person = Person.form_string("Alice-30")
静态方法
使用@staticmethod
装饰器定义,没有self
、cls
参数。与类相关,但不操作类或实例数据。更像是放在类里的普通函数,用于组织代码。
class Person:
@staticmethod
def is_adult(age):
return age >= 18
print(Person.is_adult(20))
print(Person().is_adult(20))
特殊方法(魔术方法 Magic Methods)
常用魔术方法总结:
__init__
构造方法
__del__
析构方法
__str__
打印对象的友好表示
__repr__
对象的官方表示(调试用)
__len__
len(obj)
调用
__getitem__
索引访问 obj[key]
__setitem__
赋值 obj[key] = val
__delitem__
删除 del obj[key]
__iter__
返回迭代器
__next__
迭代取值
__call__
使对象可调用
__enter__
/ __exit__
上下文管理协议(with 语句)
__eq__
, __lt__
, __gt__
比较运算符重载
__add__
, __sub__
等
运算符重载
__new__
控制实例的创建(单例模式常用)
封装
将数据(属性)和操作数据的代码(方法)捆绑在一起,并隐藏内部实现细节。
Python 中的实现:
约定:使用单下划线
_attribute
表示“受保护”的属性/方法(内部使用,不推荐外部直接访问)名称改写:使用双下划线
__attribute
定义“私有”属性/方法。Python 会将其重命名为_ClassName.__attribute
,防止意外覆盖,单并非绝对私有。属性装饰器:提供受控的访问接口(
getter/setter
)
class A:
def __init__(self):
self.public = "公开"
self._protected = "受保护"
self.__private = "私有"
a = A()
print(a.public) # ✅输出:公开
print(a._protected) # ⚠️输出:受保护 (约定不建议外部访问)
# print(a.__private) # ❌报错
print(a._A__private) # Name Mangling 后可访问
继承
一个类(子类/派生类)可以继承另外一个类(父类/基类/超类)的属性和方法,实现代码复用。
特点
子类自动拥有父类的所有共有属性和方法。
子类可以添加新的属性和方法。
子类可以重写(Override)父类的方法,提供自己的实现。
super()
函数:用于在子类中调用父类的方法。
避免硬编码父类名,提供代码灵活性和可维护性。
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name) # 调用父类 __init__
self.breed = breed
def speak(self): # 重写 speak 方法
return f"{self.name} says Woof!"
多继承
一个子类可以继承多个父类。
语法:class ChildClass(Parent1, Parent2, ...)
:
方法解析顺序:
Python 使用 C3 线性化算法确定属性和方法的查找顺序。
可以通过
ClassName.__mro__
或ClassName.mro()
查看 MRO钻石继承问题:当多个父类继承同一个祖先类时,MRO 确保祖先类的方法只被调用一次。
多态(Polymorphism)
不同类对象实现同名方法,调用时体现不同的行为。
class Cat():
def speak(self):
return "Meow"
class Dog:
def speak(self):
return "Woof"
def make_sound(animal):
print(animal.speak())
make_sound(Cat()) # Meow
make_sound(Dog()) # Woof
属性装饰器(Property)
将方法伪装成属性,提供对私有属性的安全访问(getter
,setter
,deleter
)
@property
:定义getter
方法,访问时像属性一样(obj.attr
)@attr.setter
:定义setter
方法,赋值时调用(obj.attr = value
)@atter.deleter
:定义deleter
方法,删除时调用(del obj.attr
)
class Circle:
def __init__(self, radius):
self._radius = radius # 约定私有属性
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError("半径不能为负数")
self._radius = value
@property
def area(self):
return 2.14159 * self._radius ** 2
circle = Circle(5)
print(circle.radius) # 5 (调用 getter)
circle.radius = 10 # 调用 setter
print(circle.area) # 314.159 (只读属性)
抽象基类(ABC - Abstract Base Class)
定义接口规范,强制子类必须实现某些方法。
继承abc.ABC
或使用@abstractmethod
装饰器。用@abstractmethod
装饰的方法在子类中必须被重写。包含抽象方法的类不能被实例化。
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Rectangle(Shape):
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)
# shape = Shape() # 错误! 不能实例化抽象类
rect = Rectangle(3, 4) # 正确
最后更新于