1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
Metadata-Version: 2.1
Name: codetiming
Version: 1.4.0
Summary: A flexible, customizable timer for your Python code.
Keywords: timer,class,contextmanager,decorator
Author-email: Geir Arne Hjelle <geirarne@gmail.com>, Real Python <info@realpython.com>
Requires-Python: >=3.6
Description-Content-Type: text/markdown
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Education
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Monitoring
Classifier: Typing :: Typed
Requires-Dist: dataclasses; python_version < '3.7'
Requires-Dist: black ; extra == "dev"
Requires-Dist: bump2version ; extra == "dev"
Requires-Dist: flake8 ; extra == "dev"
Requires-Dist: flit ; extra == "dev"
Requires-Dist: interrogate ; extra == "dev"
Requires-Dist: isort ; extra == "dev"
Requires-Dist: mypy ; extra == "dev"
Requires-Dist: black ; extra == "test"
Requires-Dist: interrogate ; extra == "test"
Requires-Dist: pytest ; extra == "test"
Requires-Dist: pytest-cov ; extra == "test"
Requires-Dist: tox ; extra == "test"
Project-URL: Homepage, https://realpython.com/python-timer
Project-URL: Source Code, https://github.com/realpython/codetiming
Project-URL: Tutorial, https://realpython.com/python-timer
Provides-Extra: dev
Provides-Extra: test
[](https://realpython.com/python-timer)
# `codetiming` - A flexible, customizable timer for your Python code
[](https://pypi.org/project/codetiming/)
[](https://pypi.org/project/codetiming/)
[](https://pypi.org/project/codetiming/)
[](https://github.com/realpython/codetiming/actions)
[](http://mypy-lang.org/)
[](https://interrogate.readthedocs.io/)
[](https://github.com/psf/black)
[](https://mit-license.org/)
Install `codetiming` from PyPI:
```
$ python -m pip install codetiming
```
The source code is [available on GitHub](https://github.com/realpython/codetiming).
For a complete tutorial on `codetiming`, see [Python Timer Functions: Three Ways to Monitor Your Code](https://realpython.com/python-timer) on [Real Python](https://realpython.com/).
## Basic Usage
You can use `codetiming.Timer` in several different ways:
1. As a **class**:
```python
t = Timer(name="class")
t.start()
# Do something
t.stop()
```
2. As a **context manager**:
```python
with Timer(name="context manager"):
# Do something
```
3. As a **decorator**:
```python
@Timer(name="decorator")
def stuff():
# Do something
```
## Arguments
`Timer` accepts the following arguments when it's created. All arguments are optional:
- **`name`:** An optional name for your timer
- **`text`:** The text that's shown when your timer ends. It should contain a `{}` placeholder that will be filled by the elapsed time in seconds (default: `"Elapsed time: {:.4f} seconds"`)
- **`initial_text`:** Show text when your timer starts. You may provide the string to be logged or `True` to show the default text `"Timer {name} started"` (default: `False`)
- **`logger`:** A function/callable that takes a string argument and will report the elapsed time when the logger is stopped (default: `print()`)
You can turn off explicit reporting of the elapsed time by setting `logger=None`.
In the template text, you can also use explicit attributes to refer to the `name` of the timer or log the elapsed time in `milliseconds`, `seconds` (the default), or `minutes`. For example:
```python
t1 = Timer(name="NamedTimer", text="{name}: {minutes:.1f} minutes")
t2 = Timer(text="Elapsed time: {milliseconds:.0f} ms")
```
Note that the strings used by `text` are **not** f-strings. Instead, they are used as templates that will be populated using `.format()` behind the scenes. If you want to combine the `text` template with an f-string, you need to use double braces for the template values:
```python
t = Timer(text=f"{__file__}: {{:.4f}}")
```
`text` is also allowed to be a callable like a function or a class. If `text` is a callable, it is expected to require one argument: the number of seconds elapsed. It should return a text string that will be logged using logger:
```python
t = Timer(text=lambda secs: f"{secs / 86400:.0f} days")
```
This allows you to use third-party libraries like [`humanfriendly`](https://pypi.org/project/humanfriendly/) to do the text formatting:
```python
from humanfriendly import format_timespan
t1 = Timer(text=format_timespan)
t2 = Timer(text=lambda secs: f"Elapsed time: {format_timespan(secs)}")
```
You may include a text that should be logged when the timer starts by setting `initial_text`:
```python
t = Timer(initial_text="And so it begins ...")
```
You can also set `initial_text=True` to use a default initial text.
## Capturing the Elapsed Time
When using `Timer` as a class, you can capture the elapsed time when calling `.stop()`:
```python
elapsed_time = t.stop()
```
You can also find the last measured elapsed time in the `.last` attribute. The following code will have the same effect as the previous example:
```python
t.stop()
elapsed_time = t.last
```
## Named Timers
Named timers are made available in the class dictionary `Timer.timers`. The elapsed time will accumulate if the same name or same timer is used several times. Consider the following example:
```pycon
>>> import logging
>>> from codetiming import Timer
>>> t = Timer("example", text="Time spent: {:.2f}", logger=logging.warning)
>>> t.start()
>>> t.stop()
WARNING:root:Time spent: 3.58
3.5836678670002584
>>> with t:
... _ = list(range(100_000_000))
...
WARNING:root:Time spent: 1.73
>>> Timer.timers
{'example': 5.312697440000193}
```
The example shows how you can redirect the timer output to the logging module. Note that the elapsed time spent in the two different uses of `t` has been accumulated in `Timer.timers`.
You can also get simple statistics about your named timers. Continuing from the example above:
```pycon
>>> Timer.timers.max("example")
3.5836678670002584
>>> Timer.timers.mean("example")
2.6563487200000964
>>> Timer.timers.stdev("example")
1.311427314335879
```
`timers` support `.count()`, `.total()`, `.min()`, `.max()`, `.mean()`, `.median()`, and `.stdev()`.
## Acknowledgments
`codetiming` is based on a similar module initially developed for the [Midgard Geodesy library](https://kartverket.github.io/midgard/) at the [Norwegian Mapping Authority](https://www.kartverket.no/en/).
|