Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
测量时间的Python上下文管理器_Python_With Statement - Fatal编程技术网

测量时间的Python上下文管理器

测量时间的Python上下文管理器,python,with-statement,Python,With Statement,我正在努力制作一段代码,允许测量“with”语句中花费的时间,并将测量的时间(浮点)分配给“with”语句中提供的变量 import time class catchtime: def __enter__(self): self.t = time.clock() return 1 def __exit__(self, type, value, traceback): return time.clock() - self.t w

我正在努力制作一段代码,允许测量“with”语句中花费的时间,并将测量的时间(浮点)分配给“with”语句中提供的变量

import time

class catchtime:
    def __enter__(self):
        self.t = time.clock()
        return 1

    def __exit__(self, type, value, traceback):
        return time.clock() - self.t

with catchtime() as t:
    pass
此代码保留
t=1
,而不保留clock()调用之间的差异。如何处理这个问题?我需要一种从exit方法中分配新值的方法

更详细地了解contect manager的工作原理,但我不了解其中的大部分。

几乎解决了。结果变量是可强制的,并可转换为浮点(但不是浮点本身)


您无法将时间分配给
t
。如PEP中所述,您在
As
子句中指定的变量(如果有)将被分配调用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
的结果,而不是
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。换句话说,
t
仅在
with
块的开头分配,而不是在末尾分配

您可以做的是更改
\uuuu退出\uuuu
,这样它不返回值,而是执行
self.t=time.clock()-self.t
。然后,在
with
块完成后,上下文管理器的
t
属性将保存经过的时间

要使其正常工作,您还需要从
\uuuu\uuu\uuu
返回
self
,而不是
1
。不确定使用
1
试图实现什么

看起来是这样的:

class catchtime(object):
    def __enter__(self):
        self.t = time.clock()
        return self

    def __exit__(self, type, value, traceback):
        self.t = time.clock() - self.t

with catchtime() as t:
    time.sleep(1)

print(t.t)

然后打印一个非常接近1的值。

这里是使用

输出:


执行时间:1.0014秒

@ArekBulski:就像我说的,那是不可能的。
as
行中的变量仅在
开头的
with
处赋值一次。政治公众人物对此进行了描述。
with
语句旨在让上下文管理器管理
with
块中发生的代码上下文。你可以摆弄上下文管理器并在其上存储数据,但它不能以你似乎想要的方式修改周围的环境。@ArekBulski:你能解释一下为什么它的这一方面对你如此重要吗?无论你打算用
t
做什么,只要用
t.t
就行了。这没什么大不了的。它看起来更漂亮:)Python习语中有一半是关于使事情变得漂亮的。你可以有一个属性
。seconds
。total_seconds
,我认为这更漂亮
catchtime
不能是
float
,因为float是不可变的,但当上下文退出时你想更改它。您可以实现float接口(请参见
dir(float)
)并(主要)像float一样工作,但即使这样,当需要dict
键之类的不可变对象时,您也会遇到问题。我认为与float的协同是最接近理想的。这非常简洁,非常有用。谢谢。还使用perf_counter(),这比time.clock()更好。为什么这不在标准库中?这是《20个你不使用(但应该使用)的Python库》一书中的例子吗?
class catchtime(object):
    def __enter__(self):
        self.t = time.clock()
        return self

    def __exit__(self, type, value, traceback):
        self.t = time.clock() - self.t

with catchtime() as t:
    time.sleep(1)

print(t.t)
from time import perf_counter
from contextlib import contextmanager

@contextmanager
def catchtime() -> float:
    start = perf_counter()
    yield lambda: perf_counter() - start


with catchtime() as t:
    import time
    time.sleep(1)

print(f"Execution time: {t():.4f} secs")