面向对象
类的定义
class Person:
species = "Homo sapiens" # 类变量(所有实例共享)
def __init__(self, name: str, age: int):
self.name = name # 实例变量
self.age = age
def greet(self) -> str:
return f"Hi, I'm {self.name}"
def __repr__(self) -> str:
return f"Person(name={self.name!r}, age={self.age})"
def __str__(self) -> str:
return self.name
p = Person("Alice", 30)
p.greet() # "Hi, I'm Alice"
repr(p) # "Person(name='Alice', age=30)"
继承
class Animal:
def __init__(self, name: str):
self.name = name
def speak(self) -> str:
raise NotImplementedError
class Dog(Animal):
def speak(self) -> str:
return f"{self.name} says Woof!"
# super() 调用父类
class GuideDog(Dog):
def __init__(self, name: str, owner: str):
super().__init__(name)
self.owner = owner
def speak(self) -> str:
return super().speak() + " (guide dog)"
多重继承与 MRO
class A:
def hello(self): return "A"
class B(A):
def hello(self): return "B"
class C(A):
def hello(self): return "C"
class D(B, C):
pass
D().hello() # "B"(MRO:D → B → C → A)
D.__mro__ # 查看方法解析顺序
访问控制(约定)
class BankAccount:
def __init__(self, balance: float):
self.owner = "Alice" # 公开
self._balance = balance # 约定受保护
self.__pin = "1234" # 名称改写(name mangling)
# 实际存储为 _BankAccount__pin
property
class Circle:
def __init__(self, radius: float):
self._radius = radius
@property
def radius(self) -> float:
return self._radius
@radius.setter
def radius(self, value: float):
if value < 0:
raise ValueError("Radius cannot be negative")
self._radius = value
@property
def area(self) -> float:
import math
return math.pi * self._radius ** 2
c = Circle(5)
c.radius = 10 # 调用 setter
c.area # 314.159...
classmethod 与 staticmethod
class Date:
def __init__(self, year, month, day):
self.year, self.month, self.day = year, month, day
@classmethod
def from_string(cls, s: str) -> "Date":
y, m, d = map(int, s.split("-"))
return cls(y, m, d)
@staticmethod
def is_valid(year, month, day) -> bool:
return 1 <= month <= 12 and 1 <= day <= 31
Date.from_string("2024-01-15")
Date.is_valid(2024, 13, 1) # False
常用魔术方法
class Vector:
def __init__(self, x, y):
self.x, self.y = x, y
def __repr__(self): return f"Vector({self.x}, {self.y})"
def __add__(self, other): return Vector(self.x+other.x, self.y+other.y)
def __mul__(self, n): return Vector(self.x*n, self.y*n)
def __rmul__(self, n): return self.__mul__(n)
def __eq__(self, other): return self.x == other.x and self.y == other.y
def __abs__(self): return (self.x**2 + self.y**2) ** 0.5
def __iter__(self): return iter((self.x, self.y))
def __len__(self): return 2
| 魔术方法 | 触发场景 |
|---|
__init__ | 实例化 |
__repr__ | repr() / 调试 |
__str__ | str() / print() |
__len__ | len() |
__getitem__ | obj[key] |
__contains__ | x in obj |
__call__ | obj() |
__enter__/__exit__ | with 语句 |
__hash__ | hash() / 字典键 |
dataclass(Python 3.7+)
from dataclasses import dataclass, field
@dataclass
class Point:
x: float
y: float
z: float = 0.0
tags: list = field(default_factory=list)
def distance(self) -> float:
return (self.x**2 + self.y**2 + self.z**2) ** 0.5
# 自动生成 __init__、__repr__、__eq__
@dataclass(frozen=True) # 不可变,自动生成 __hash__
class ImmutablePoint:
x: float
y: float
抽象类
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self) -> float: ...
@abstractmethod
def perimeter(self) -> float: ...
class Rectangle(Shape):
def __init__(self, w: float, h: float):
self.w, self.h = w, h
def area(self) -> float: return self.w * self.h
def perimeter(self) -> float: return 2 * (self.w + self.h)
相关链接