list、tuple、dict 等没有直接继承 Iterable, 它们通过实现 __iter__() 方法来实现 Iterable 接口 java有Interface这种类型,class去implement;或者抽象类,extends继承抽象类,重写抽象方法 python有没有
Python通过抽象基类(Abstract Base Classes, ABCs) 和鸭子类型(Duck Typing) 来实现类似Java接口和抽象类的功能。
__iter__
),就被视为“实现了该接口”。class MyRange: # 没有继承任何基类 def __init__(self, n): self.n = n def __iter__(self): # 实现迭代协议 for i in range(self.n): yield i
使用时:
for x in MyRange(3): # Python 只关心有没有 __iter__ print(x)
abc
模块里提供了 ABC
与 @abstractmethod
,需要显式继承并强制子类实现抽象方法。
from abc import ABC, abstractmethod class Drawable(ABC): @abstractmethod def draw(self): # 抽象方法 pass class Circle(Drawable): def draw(self): print("画圆") # Drawable() # 实例化会抛 TypeError Circle() # 必须实现 draw 才能实例化
或者:
from abc import ABC, abstractmethod # 定义一个"接口"(抽象基类) class Animal(ABC): @abstractmethod def speak(self) -> str: """动物会叫的方法""" pass @abstractmethod def move(self) -> None: """动物会移动的方法""" pass # 实现这个"接口" class Dog(Animal): # 类似Java的implements def speak(self) -> str: return "Woof!" def move(self) -> None: print("Dog is running") class Cat(Animal): # 类似Java的implements def speak(self) -> str: return "Meow!" def move(self) -> None: print("Cat is walking") # 使用 dog = Dog() print(dog.speak()) # Woof! # 不能实例化抽象类 # animal = Animal() # 会报错: TypeError
from abc import ABC, abstractmethod class Drawable(ABC): @abstractmethod def draw(self) -> None: pass # 第三方类,不能修改其继承关系 class Circle: # 没有继承Drawable def draw(self) -> None: print("Drawing circle") # 但我们可以注册它 Drawable.register(Circle) # 现在Circle被认为是Drawable circle = Circle() print(isinstance(circle, Drawable)) # True print(issubclass(Circle, Drawable)) # True
from typing import Protocol class Sized(Protocol): def __len__(self) -> int: ... def report_size(obj: Sized) -> None: print(len(obj)) report_size([1, 2, 3]) # 列表实现了 __len__ report_size("hello") # 字符串也实现了 __len__
运行时并不强制继承,但静态检查器要求对象必须“看上去像”协议。
abc.ABC
+ @abstractmethod
。typing.Protocol
__iter__
),就被视为“实现了该接口”。class MyRange: # 没有继承任何基类
def __init__(self, n):
self.n = n
def __iter__(self): # 实现迭代协议
for i in range(self.n):
yield i
for x in MyRange(3): # Python 只关心有没有 __iter__
print(x)
abc
模块里提供了 ABC
与 @abstractmethod
,需要显式继承并强制子类实现抽象方法。from abc import ABC, abstractmethod
class Drawable(ABC):
@abstractmethod
def draw(self): # 抽象方法
pass
class Circle(Drawable):
def draw(self):
print("画圆")
# Drawable() # 实例化会抛 TypeError
Circle() # 必须实现 draw 才能实例化
from typing import Protocol
class Sized(Protocol):
def __len__(self) -> int: ...
def report_size(obj: Sized) -> None:
print(len(obj))
report_size([1, 2, 3]) # 列表实现了 __len__
report_size("hello") # 字符串也实现了 __len__
Python有抽象基类(abc.ABC
+ @abstractmethod
),最接近Java的接口/抽象类
但Python更推荐鸭子类型:不关心是否继承,只关心是否有相应方法
collections.abc
模块:提供了很多预定义的抽象基类(如 Iterable
, Iterator
, Sequence
等)
注册机制:可以让现有的类"看起来"实现了某个接口
所以对于 list
, tuple
, dict
等内置类型,它们通过:
实现相应的方法(如 __iter__()
)
被注册到相应的抽象基类(如 Iterable.register(list)
)