Should import statements always be at the top of a module?

后端 未结 20 1998
醉酒成梦
醉酒成梦 2020-11-22 02:56

PEP 08 states:

Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.<

20条回答
  •  离开以前
    2020-11-22 03:53

    I was surprised not to see actual cost numbers for the repeated load-checks posted already, although there are many good explanations of what to expect.

    If you import at the top, you take the load hit no matter what. That's pretty small, but commonly in the milliseconds, not nanoseconds.

    If you import within a function(s), then you only take the hit for loading if and when one of those functions is first called. As many have pointed out, if that doesn't happen at all, you save the load time. But if the function(s) get called a lot, you take a repeated though much smaller hit (for checking that it has been loaded; not for actually re-loading). On the other hand, as @aaronasterling pointed out you also save a little because importing within a function lets the function use slightly-faster local variable lookups to identify the name later (http://stackoverflow.com/questions/477096/python-import-coding-style/4789963#4789963).

    Here are the results of a simple test that imports a few things from inside a function. The times reported (in Python 2.7.14 on a 2.3 GHz Intel Core i7) are shown below (the 2nd call taking more than later calls seems consistent, though I don't know why).

     0 foo:   14429.0924 µs
     1 foo:      63.8962 µs
     2 foo:      10.0136 µs
     3 foo:       7.1526 µs
     4 foo:       7.8678 µs
     0 bar:       9.0599 µs
     1 bar:       6.9141 µs
     2 bar:       7.1526 µs
     3 bar:       7.8678 µs
     4 bar:       7.1526 µs
    

    The code:

    from __future__ import print_function
    from time import time
    
    def foo():
        import collections
        import re
        import string
        import math
        import subprocess
        return
    
    def bar():
        import collections
        import re
        import string
        import math
        import subprocess
        return
    
    t0 = time()
    for i in xrange(5):
        foo()
        t1 = time()
        print("    %2d foo: %12.4f \xC2\xB5s" % (i, (t1-t0)*1E6))
        t0 = t1
    for i in xrange(5):
        bar()
        t1 = time()
        print("    %2d bar: %12.4f \xC2\xB5s" % (i, (t1-t0)*1E6))
        t0 = t1
    

提交回复
热议问题