使用 timeit.timeit 的 globals 参数

Jon*_*han 5 python-3.5

我正在尝试在以下类中运行 timeit.timeit:

from contextlib import suppress
from pathlib import Path
import subprocess
from timeit import timeit


    class BackupVolume():
        '''
        Backup a file system on a volume using tar
        '''
        targetFile = "bd.tar.gz"
        srcPath = Path("/BulkData")
        excludes = ["--exclude=VirtualBox VMs/*",  # Exclude all the VM stuff
                    "--exclude=*.tar*"]            # Exclude this tar file

        @classmethod
        def backupData(cls, targetPath="~"):  # pylint: disable=invalid-name
            '''
            Runs tar to backup the data in /BulkData so we can reorganize that
            volume. Deletes any old copy of the backup repository.

            Parameters:
            :param str targetPath: Where the backup should be created.
            '''

            # pylint: disable=invalid-name
            tarFile\
                = Path(Path(targetPath /
                       cls.targetFile).resolve())
            with suppress(FileNotFoundError):
                tarFile.unlink()
            timeit('subprocess.run(["tar", "-cf", tarFile.as_posix(),'
                   'cls.excludes[0], cls.excludes[1], cls.srcPath.as_posix()])',
                   number=1, globals=something)
Run Code Online (Sandbox Code Playgroud)

我的问题是在timeit()内部它无法解释subprocess。我相信timeit()globals参数应该有帮助,但我不知道如何指定模块命名空间。有人可以告诉我怎么做吗?

Gui*_*sch 5

我认为在您的情况下globals = globals()timeit电话会起作用。

解释

globals参数指定在其上执行该代码命名空间。由于您导入了subprocess模块(在函数之外,甚至在类之外),您可以使用globals(). 通过这样做,您可以访问当前模块的字典,您可以在docs 中找到更多信息。

超级简单的例子

在这个例子中,我将展示 3 个不同的场景。

  1. 需要访问全局变量
  2. 需要访问本地人
  3. 自定义命名空间

遵循示例的代码:

import subprocess
from timeit import timeit
import math


class ExampleClass():

    def performance_glob(self):
        return timeit("subprocess.run('ls')", number = 1, globals = globals())

    def performance_loc(self):
        a = 69
        b = 42
        return timeit("a * b", number = 1, globals = locals())

    def performance_mix(self):
        a = 69
        return timeit("math.sqrt(a)", number = 1, globals = {'math': globals().get('math'), 'a': locals().get('a')})
Run Code Online (Sandbox Code Playgroud)
  1. performance_glob您计时需要全局导入的东西时,模块subprocess. 如果您不传递 globals 命名空间,您将收到这样的错误消息NameError: name 'subprocess' is not defined
  2. 相反,如果你传递globals()给取决于当地值函数performance_loc的使用timeit执行所需的变量a,并b不会在范围内。这就是为什么你可以使用locals()
  3. 最后一个是一般情况,您需要函数中的本地变量和一般导入。如果您记住参数globals可以指定为字典,您只需要提供必要的键,您就可以自定义它。