Python类的首选结构:子类化和依赖性

时间:2014-04-22 19:15:35

标签: python python-2.7 dependencies subclassing

我正在构建一个类来处理基于字符串输入的绘图。我希望能够将图形输出到png和svg图像。我处理输入模式以创建将用于构造两种输出格式的图形的抽象。

这个抽象是一个定义形状的对象数组,它将由两个独立的方法迭代,一个使用我们的数据来构建svg元素,使用我为任务编写的自定义模块,另一个使用{{1} }库创建输出到png的形状。这两种方法都没有问题,代码都正常工作,我的输出是预期的。

我的问题是效率问题,因为此代码将在服务器上运行,并将用于从API返回图像数据。目前我的代码结构如下:

PIL

每个渲染方法都有单独的依赖;必须加载以执行绘图的库。对于任何给定的API响应,只会调用一个呈现方法,因此我希望每次class Pattern: def __init__(self, input_pattern): self.pattern = input_pattern self.data = self.__process() def __process(self): # processes the input, returning an array # of custom shape objects # which will be read by the render methods def renderSVG(self): # uses self.data to render an svg def renderPNG(self): # uses self.data to render a png 实例化时都避免为其他方法加载依赖项。

我想到了两种可能的解决方案:

解决方案1。在渲染方法中导入库。

例如:

Pattern

这是否气馁?我总是在文件的顶部导入模块,而不是在其中。看起来这样可行,但我想知道是否有充分的理由避免这样做,因为我很少看到它。

解决方案2. 为不同格式制作子类。

例如,从基类中删除两个render方法,并在单独的文件中删除:

class Pattern:
  # initialization etc...
  def renderPNG:
    import PIL
    # use PIL to render png

这也可以,但是像这样的子类化的成本是多少?处理from theModuleDescribedAbove import Pattern import PIL class PNGPattern(Pattern): def __init__(self, input_pattern): Pattern.__init__(self, input_pattern) def render(self): # use PIL to render png 类中的输入的代码比任何一种渲染方法都要长,但不如Pattern模块大。它必须在可以使用之前导入,与在解决方案1中使用的文件相比,它是否会显着减慢速度?

哪种方法可能效率最高?有没有更好的方法,我没有想到?任何建议或意见将不胜感激。

2 个答案:

答案 0 :(得分:3)

如果这是服务器上的API,可能它是Web框架的一部分,并通过WSGI提供服务。在这种情况下,您认为为每个请求加载依赖项是错误的。它们不是:一个进程被实例化以处理请求,并且将持续存在许多请求。在该过程中,一旦导入模块,它们将保留在内存中:后续导入语句导致代码再次加载。

因此,总而言之,您不必要地担心,这不是效率低下的原因。

答案 1 :(得分:1)

使用内联导入模块的解决方案应该没问题。没有与此相关的任何性能损失。遇到import语句时,python会执行引用的模块中的所有顶级代码。完成此操作后,它会将模块缓存在标准库变量sys.modules中。随后,从sys.modules检索模块,而不是重新解析/重新执行。为了清晰起见,人们倾向于支持文件顶部的导入。它使人们更容易阅读代码,以确切了解给定文件中正在使用的模块。作为旁注,使用本地导入可以更快,因为python中的局部变量比全局变量检索得更快。

正如Daniel所说,WSGI应用程序往往由许多进程提供服务,这些进程由Gunicorn或Uwsgi等应用程序服务器预先提供。只要进程继续运行,它们就会累积已在sys.modules中导入的任何模块。这些模块不会缓存在sys.modules中,直到它们被进程的启动代码或处理请求时执行的视图代码导入。