Python 协议总结

102 阅读2分钟

摘要:

Python 语言的灵活性很大程度上源于其基于协议或者约定的设计理念。这些协议为不同的功能提供了一种标准化接口,开发者可以实现自定义行为同时可以使用 python 语法糖来使用这些协议。本篇主要总结这些协议或者约定。

迭代器协议(Iterator Protocol)

用途: 此协议主要支持对象的迭代行为(for 循环、 列表推导等) 核心方法:

  • __iter__(): 返回一个迭代器对象。
  • __next__(): 返回下一个值
class MyIterator:

    def __init__(self, data):
        self.data = data
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index < len(self.data):
            value = self.data[self.index]
            self.index += 1
            return value
        raise StopIteration

obj = MyIterator([1, 2, 3])

for x in obj:
    print(x)  # 输出 1, 2, 3

序列协议(Sequence Protocol)

用途: 支持对象作为序列操作(如索引、切片、迭代)。

核心方法:

  • __getitem__(index): 返回指定索引的值。
  • __len__(): 返回序列的长度。
class MySequence:
    def __init__(self, data):
        self.data = data

    def __getitem__(self, index):
        return self.data[index]

    def __len__(self):
        return len(self.data)

obj = MySequence([1, 2, 3])
print(len(obj))       # 输出 3
print(obj[1])         # 输出 2
for item in obj:
    print(item)       # 输出 1, 2, 3

上下文管理协议(Context Management Protocol)

用途: 支持 with 语句,用于资源管理(如文件操作)。

核心方法:

  • __enter__(): 进入上下文,返回资源对象。
  • __exit__(exc_type, exc_value, traceback): 离开上下文,清理资源。
class MyContext:
    def __enter__(self):
        print("Entering context")
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        print("Exiting context")

with MyContext():
    print("Inside context")
# 输出:
# Entering context
# Inside context
# Exiting context

可调用对象协议(Callable Protocol)

用途: 允许对象表现得像函数一样,可以被调用。

核心方法:

• __call__(*args, **kwargs): 定义对象被调用时的行为。

class MyCallable:
    def __call__(self, *args, **kwargs):
        return f"Called with args={args} kwargs={kwargs}"

obj = MyCallable()
print(obj(1, 2, key="value"))  # 输出: Called with args=(1, 2) kwargs={'key': 'value'}

描述符协议(Description Protocol)

用途: 用于定制属性的访问、赋值和删除行为(如 property 的实现)。

核心方法:

• __get__(self, instance, owner): 获取属性时调用。

• __set__(self, instance, value): 设置属性时调用。

• __delete__(self, instance): 删除属性时调用。

class MyDescriptor:
    def __get__(self, instance, owner):
        return "Getting value"
    
    def __set__(self, instance, value):
        print(f"Setting value: {value}")
    
    def __delete__(self, instance):
        print("Deleting value")

class MyClass:
    attr = MyDescriptor()

obj = MyClass()
print(obj.attr)       # 输出: Getting value
obj.attr = 42         # 输出: Setting value: 42
del obj.attr          # 输出: Deleting value

数字协议(Numeric Protocol)

用途: 支持算术运算符(如 +、-)。

核心方法:

• __add__, __sub__, __mul__, 等等。

class MyNumber:
    def __init__(self, value):
        self.value = value

    def __add__(self, other):
        return MyNumber(self.value + other.value)

    def __repr__(self):
        return str(self.value)

num1 = MyNumber(10)
num2 = MyNumber(20)
print(num1 + num2)  # 输出 30

WSGI 协议(Web Server Gateway Interface)

用途: 用于 Web 应用和服务器之间的通信。

核心要求:

• 必须是一个可调用对象(如函数或类的实例)。

• 接受两个参数:environ(请求信息)和 start_response(发送响应的方法)。

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return [b"Hello, WSGI!"]