使用timeit.timeit的globals参数

时间:2017-07-03 17:11:55

标签: 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)

我遇到的问题是在 timeit()内部无法解释子流程。我相信 timeit()全局参数应该会有所帮助,但我不知道如何指定模块命名空间。有人能告诉我怎么样?

1 个答案:

答案 0 :(得分:2)

我认为在globals = globals()调用中timeit可能会有效。

<强>解释

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

超级简单示例

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

  1. 需要访问全局
  2. 需要访问本地人
  3. 自定义命名空间
  4. 代码遵循示例:

    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')})
    
    1. performance_glob中,您需要进行全局导入,模块subprocess。如果您未通过全局命名空间,则会收到类似NameError: name 'subprocess' is not defined
    2. 的错误消息
    3. 相反,如果您将globals()传递给依赖于本地值performance_loc的函数,则执行时间ab所需的变量将获胜。在范围内。这就是您可以使用locals()
    4. 的原因
    5. 最后一个是一般情况,您需要功能和常规导入中的本地变量。如果您记住参数globals可以指定为字典,您只需提供必要的密钥,您就可以自定义它。