我的项目包含大量进口,这些进口位于“全球”范围内。
from google.appengine.ext import ndb
from handlers import SomeHandler
import logging
import datetime # will only use this module ONCE
我想在特定处理程序中使用{strong>一次的datetime
模块。我应该在处理程序中导入日期时间还是应该将其保留在全局范围内?
import datetime # Should we import here?
class BookHandler(webapp2.RequestHandler):
import datetime # Or, should we import here?
def get(self):
today = datetime.datetime.now()
似乎本地导入显示更清晰的依赖关系。是否存在性能问题或其他缺点需要考虑?
答案 0 :(得分:1)
你应该在文件的开头挑出模块,将模块绑定到该文件的范围。我认为你正在做的事情被称为“延迟加载”模块,如果未正确安装或导入模块,它可能会在运行时导致错误。
顺便说一句,python的工作方式是每次导入模块时,解释器会查看模块是否已导入。如果已导入,则会设置对它的引用。换句话说,它不会创建它的新实例。
我建议为您的处理程序类创建一个文件,并在该文件的开头导入日期时间和其他任何内容。
答案 1 :(得分:1)
在处理程序内部导入没有问题(如果您愿意,甚至可以在get()
函数内部导入) - 我正在大量使用它。
延迟加载的优点:
延迟加载的缺点:
相关(仅在延迟加载意义上):App Engine: Few big scripts or many small ones?
答案 2 :(得分:1)
隐藏这样的进口是一种优化;无论何时考虑是否优化,都要验证所提议的优化是否真的有效。
让我们首先考虑datetime
的具体示例。这是一个简单的应用程序:
import sys
import webapp2
class Handler(webapp2.RequestHandler):
def get(self):
if 'datetime' in sys.modules:
self.response.write('The datetime module is already loaded.\n')
else:
self.response.write('The datetime module is not already loaded\n.')
self.response.write('%d modules have been loaded\n' % len(sys.modules))
count = sum(1 for x in sys.modules.values() if '/lib64' in repr(x))
self.response.write('%d standard library modules have been loaded\n' % count)
gcount = sum(1 for x in sys.modules.values() if 'appengine' in repr(x))
self.response.write('%d appengine modules have been loaded\n' % gcount)
application = webapp2.WSGIApplication([('/', Handler)])
如果我们访问'/'网址,我们会看到此输出:
日期时间模块已加载。
已加载706个模块
已加载95个标准库模块
已加载207个appengine模块
即使在这个最小的应用中,SDK {sup> * 也已导入datetime
。 Python导入模块后,进一步导入只需要一次字典查找,因此隐藏导入没有任何好处。鉴于SDK已经导入了95个标准库模块和207个SDK模块,因此隐藏了常用标准库或SDK模块的导入不太可能有很多好处。
这就留下了导入应用程序代码的问题。处理程序可以通过在路由中将它们声明为字符串来延迟加载,以便在访问路径之前不会导入它们:
app = webapp2.Application([('/foo', 'handlers.FooHandler')])
如果您发现有必要,此技术允许优化启动时间而不隐藏类或方法中的导入。
其他答案指出,延迟加载的成本可能是意外的运行时错误。此外,如果您选择隐藏导入,它也会降低代码可读性,可能导致结构问题,例如屏蔽循环依赖关系,并为经验不足的开发人员设置一个糟糕的示例,他们可能认为隐藏导入是惯用的而不是优化。 / p>
因此,在考虑以这种方式进行优化时:
* 我希望,依赖于SDK的sys.modules
类似于云运行时,是一个合理的假设。