Skip to main content
 首页 » 编程设计

python之django/python 导入性能

2025年05月04日37zfyouxi

有人可以证明为什么使用这样的解决方案是不好的做法吗:

在django views中98%的情况下你需要使用

  from django.http import HttpResponseRedirect 
  from django.core.urlresolvers import reverse 
  from django.utils.translation import ugettext as _ 

无论如何,在我的项目中,我的每个 View 都有这些导入,并且几乎在 View 的每个第二个函数中都使用了所有内容:

from datetime import datetime 
from django.conf import settings 
from django.contrib.auth.models import User 
from django.core.urlresolvers import reverse 
from django.core import paginator 
from django.db import connection 
from django.db.models import Q 
from django.http import HttpResponseRedirect, Http404, HttpResponse 
from django.shortcuts import render_to_response, get_object_or_404 
from django.template import RequestContext 
from django.utils.translation import ugettext as _ 

现在加上一些模型和表格,我有50行根本看不懂的废话。

我想到的第一件事当然是创建更多 View ,拆分一些操作等等。但仍然有大约 30 行导入扼杀了我在代码中的定位。

然后我决定将 95% 的时间在 View 中使用的所有内容放到目录/project/app/imports/view.py 中。现在我只用ONE导入就拥有了所有常见的东西,但是我的同事攻击了我,说阅读这种代码非常困难,因为你看不到导入的内容,以及为什么见鬼,在你的 IDE 中再打开一个选项卡这么难……??? [尤其是 vim 用户,他们有 FRAMES,而他正在使用 vim]

我对模型做了同样的事情,我的模型有自己的目录,因为里面有 50 多个,而且这些文件不小——每个大约 150 行。即使这些文件里面也只有很少的模型。所以我我只是在做类似的事情:

from myapp.models.mymodel import * 

有些地方我只是在做:from myapp.models import * [init.py of myapp/imports dir takes here]

问题:

1) 好吧,第一个问题是命名空间,这种模型导入可能真的很荒谬..但是 View 和表单的决定,只不过是懒惰在你的 IDE 中打开一个标签

2) 性能问题?我的同事真的对这个论点争论不休,“每次导入都需要 256kb 的 ram”?? (通过运行编译的 .pyc 文件?不,我不相信;)

问题其实是导入导致的性能问题。

附注我真的是 python 的新手(只有 3 个月),我对关于这个解决方案的所有利弊的目标论点持开放态度。

更新

有一次我问了关于如何将导入移动到独立文件的问题,所以没有人提示这个 =) 问题是 here

请您参考如下方法:

1) 不在导入的名称前面加上它来自的模块只是懒惰。不愿意滚动代码的导入只是懒惰。在另一个文件中导入那些乱七八糟的东西到底是如何让它更容易阅读的呢?我会将其保留在实际使用它们的原始文件中。这提高 可读性,因为如果我需要知道某些东西来自哪里,那么我可以直接转到文件的顶部并检查它(使用 emacs 标记环返回)。它还使维护列表变得更容易,因为我只需要快速搜索以查看使用(或未使用)某些内容的位置。

2) 在我的机器上,导入一个模块大约需要 812 微秒。

$ python -mtimeit -s'import os' 'reload(os)' 
1000 loops, best of 3: 808 usec per loop 

这当然会随着它在 PYTHONPATH 中的位置而有很大差异。如果性能那么紧张,您可以通过杂耍来挤出一些。 YMMV.

我不确定您的同事从哪里获得 256kb。这将取决于所涉及的代码对象的大小。

>>> import sys 
>>> sys.getsizeof(sys) 
24 
>>> sys.getsizeof(sys.modules['__main__']) 
24 

如您所见,实际的模块对象在我的 32 位机器上只占用 24 个字节。不过,我觉得这将取决于系统。

>>> def sizeofmodule(mod): 
...     return sum(sys.getsizeof(getattr(mod, o)) for o in dir(mod)) 
...  
>>> sizeofmodule(itertools) 
8662 
>>> sizeofmodule(sys) 
10275 
>>> sizeofmodule(operator) 
5230