我正在尝试编写一个简单的插件系统。
a) 为此,我找到了使用 3.6 魔术函数__init_subclass__ /sf/answers/2934703201/的以下代码,该函数改编自 PEP 487,它注册列表中父类中定义的每个类plugins。
b)我现在想“强制”插件的编写者实现一个特定的方法,该方法将由我的程序调用。理想情况下,这会在导入时警告用户,他的插件将无法工作,但不会阻止程序运行。为此,我尝试将 ABC 添加为插件的父类,并添加一个@abstractmethod.
我最初尝试 ABC 和__init_subclass__:
from abc import ABC, abstractmethod
class Plugin(ABC):
plugins = []
@classmethod
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
try:
__class__.plugins.append(cls()) # Does not raise exception
except Exception as e:
print("Warning: Your plugin might not work, missing abstract method")
@abstractmethod
def do_something(self):
...
class Render(Plugin):
def __init__(self):
print("Render init")
# does not implement 'do_something'
for plugin in Plugin.plugins:
plugin.do_something() # Calls 'do_something' …Run Code Online (Sandbox Code Playgroud) 测试下载网页源的不同可能性我得到了以下结果(google.com,9gag.com的平均时间毫秒):
所以对于我的9gag客户端,我决定采用gzip HttpWebRequest.问题是,在我的实际程序中实现后,请求所需的时间超过两倍.
只在两个请求之间添加Thread.Sleep时也会出现问题.
编辑:
只是改进了一点代码,仍然是同样的问题:当在循环中运行时,当我在请求之间添加延迟时,请求需要更长的时间
for(int i = 0; i < 100; i++)
{
getWebsite("http://9gag.com/");
}
Run Code Online (Sandbox Code Playgroud)
每个请求大约需要250毫秒.
for(int i = 0; i < 100; i++)
{
getWebsite("http://9gag.com/");
Thread.Sleep(1000);
}
Run Code Online (Sandbox Code Playgroud)
每个请求大约需要610毫秒.
private string getWebsite(string Url)
{
Stopwatch stopwatch = Stopwatch.StartNew();
HttpWebRequest http = (HttpWebRequest)WebRequest.Create(Url);
http.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
string html = string.Empty;
using (HttpWebResponse webResponse = (HttpWebResponse)http.GetResponse())
using (Stream responseStream = webResponse.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
{
html = …Run Code Online (Sandbox Code Playgroud)