Python 代理模式(proxy)
简介
代理模式是一种结构型设计模式,它允许通过提供一个代理对象来控制对其他对象的访问。代理对象充当了目标对象的中间人,它可以在目标对象被访问前或访问后加入一定的处理逻辑。在许多情况下,代理模式可以提供非常便利的解决方案,例如实现延迟初始化、对敏感信息进行保护、远程代理等。
在 Python 中,我们可以借助一些库来实现代理模式,比如使用 requests
库来创建一个简单的 HTTP 代理。在本文中,我们将详细介绍 Python 代理模式的概念、工作原理以及如何在实际应用中使用代理模式。
工作原理
代理模式包含两个主要角色:目标对象和代理对象。目标对象是我们希望访问的真实对象,而代理对象是用于控制对目标对象的访问的对象。
下面以一个简单示例来说明代理模式的工作原理:
class RealSubject:
def request(self):
print("RealSubject: 处理请求")
class Proxy:
def __init__(self, real_subject):
self.real_subject = real_subject
def request(self):
if self.check_access():
self.real_subject.request()
def check_access(self):
print("Proxy: 验证访问权限")
return True
proxy = Proxy(RealSubject())
proxy.request()
在上面的示例中,RealSubject
是目标对象,它定义了一个 request
方法来处理请求。Proxy
是代理对象,它接收一个 real_subject
参数,即目标对象的实例。当调用代理对象的 request
方法时,首先会调用 check_access
方法进行权限验证,然后再调用真实对象的 request
方法来处理请求。
运行上述代码的输出结果如下:
Proxy: 验证访问权限
RealSubject: 处理请求
可以看到,代理对象在访问目标对象之前进行了权限验证,并且代理对象在不修改目标对象的情况下添加了额外的逻辑。
代理模式的应用场景
代理模式在很多实际应用中都有广泛的应用,下面介绍几种常见的应用场景。
延迟初始化
使用代理对象可以实现延迟初始化的功能,即在需要的时候才创建真正的目标对象。这种方式可以避免在程序启动时就创建不必要的对象,从而提高性能和内存利用率。
class RealSubject:
def __init__(self):
print("正在初始化 RealSubject")
def request(self):
print("RealSubject: 处理请求")
class Proxy:
def __init__(self):
self.real_subject = None
def request(self):
if self.real_subject is None:
self.real_subject = RealSubject()
self.real_subject.request()
proxy = Proxy()
print("在调用 request 方法之前")
proxy.request()
print("在调用 request 方法之后")
proxy.request()
运行上述代码的输出结果如下:
在调用 request 方法之前
正在初始化 RealSubject
RealSubject: 处理请求
在调用 request 方法之后
RealSubject: 处理请求
可以看到,真实对象 RealSubject
的初始化是在第一次调用代理对象的 request
方法时才进行的,而不是在创建代理对象时立即进行。
保护代理
保护代理可以对目标对象进行访问控制,只有满足一定条件的客户端才能访问目标对象。代理对象在访问目标对象之前先进行权限验证,如果验证通过才会调用目标对象的方法。
class RealSubject:
def __init__(self, password):
self.password = password
def request(self):
print("RealSubject: 处理请求")
class Proxy:
def __init__(self, real_subject, password):
self.real_subject = real_subject
self.password = password
def request(self):
if self.check_access():
self.real_subject.request()
def check_access(self):
user_input = input("请输入密码: ")
return user_input == self.password
password = "123456"
real_subject = RealSubject(password)
proxy = Proxy(real_subject, password)
proxy.request()
运行上述代码时,会要求用户输入密码。只有输入的密码与初始化时设置的密码相同时,才会调用真实对象的方法。
远程代理
远程代理可以隐藏目标对象跟客户端之间的网络通信细节。客户端通过访问代理对象来间接访问远程的目标对象。
下面以一个简单的示例来说明远程代理的使用方式:
import requests
class RemoteSubject:
def request(self):
response = requests.get("https://www.example.com")
print("远程请求完成,状态码:", response.status_code)
class Proxy:
def __init__(self):
self.remote_subject = RemoteSubject()
def request(self):
print("代理正在进行网络请求")
self.remote_subject.request()
proxy = Proxy()
proxy.request()
上述代码中,RemoteSubject
是远程目标对象的类,它在 request
方法中发送了一个网络请求。Proxy
是代理对象,它在 request
方法中先输出一条提示信息,然后调用远程目标对象的 request
方法。
运行上述代码时,可以看到代理对象先输出了一条提示信息,然后再进行网络请求。
总结
代理模式是一种结构型设计模式,它可以通过提供代理对象来控制对其他对象的访问。代理对象充当了目标对象的中间人,它可以在目标对象被访问前或访问后加入一定的处理逻辑。
在 Python 中,我们可以借助一些库来实现代理模式。代理模式的应用场景很多,例如延迟初始化、保护代理和远程代理等。通过使用代理模式,我们可以对目标对象进行访问控制、隐藏远程通信细节等。