{"body": "
\n

# The Collector in-depth\u00b6

\n

This sections provides a more in-depth description of the\n`Collector` class and some of the shortcut functions.

\n
\n

## How `Collector` works\u00b6

\n

The Collector needs two things to monitor a variable:

\n

\n
1. A name that identifies the variable and its series within the collector
\n
2. A collector function that gets the current value of the variable each time\nthe collector is called.
\n

\n

When you create a new collector, you must pass a tuple `(name,\ncollector_func)` for each variable you want to monitor:

\n

    >>> from collectors import Collector\n>>> a = 1\n>>> b = 2\n>>>\n>>> def get_b(factor):\n...     return factor * b\n...\n>>> c = Collector(\n...     ('a', lambda: a),\n...     ('b', get_b)\n... )\n

\n
\n

A variable\u2019s name must be a string and should also be a valid Python\nidentifier. The\ncollector function can be anything that\u2019s callable\u2014it might even take a\nparameter.

\n

By default, the Collector creates a Python list for each variable which will\nhold all monitored values. We will call this list series here.

\n

The series for a variable is accessible either by index or as an attribute (this\nis why name should be a valid identifier):

\n

    >>> c\n([], [])\n>>> c[0] == c.a, c[1] == c.b\n(True, True)\n

\n
\n

Each time the Collector (or its `collect()`\nmethod) is called, it calls every collector function in the order they were\ninitially passed to it and appends their return value to each variable\u2019s\nseries. If a collector function needs a parameter, you must pass it as\nkeyword argument:

\n

    >>> c\n([], [])\n>>> c(b=4) # c.collect(b=4) would do the same\n>>> c\n([1], [8])\n

\n
\n
\n

### Summary\u00b6

\n

\n
- Each variable is described by a name, a collector function and a series.
\n
- The series are ordered in the same way the `(name, col_func)` tuples were\npassed to the Collector\u2019s constructor.
\n
- A collector function can optionally have (exactly) one argument.
\n
- Each call to the Collector or its `collect` method collects the current\nvalues of all monitored variables.
\n
- If a collector functions needs an argument, it must be passed as keyword\nargument to `__call__` or `collect` and the key must be the same as\nname.
\n

\n
\n
\n
\n

## Shortcut functions\u00b6

\n

Collectors has some shortcut functions included that help you save typing.\nThey are defined in `collectors.shortcuts` but can also be import directly\nfrom `collectors` for even less typing. ;-)

\n
\n

### Monitor several attributes of one object\u00b6

\n

In most cases you\u2019ll probably end up using Collectors like this:

\n

    >>> class Spam(object):\n...     def __init__(self, a, b, c):\n...         self.a = a\n...         self.b = b\n...         self.c = c\n...\n...         self.collector = Collector(\n...             ('a', lambda: self.a),\n...             ('b', lambda: self.b),\n...             ('c', lambda: self.c),\n...         )\n

\n
\n

Setting up a Collector like this is very tedious and repetitive. The shortcut\n`get()` allows you to create these tuples much faster:

\n

    >>> from collectors import get\n>>> class Spam(object):\n...     def __init__(self, a, b, c):\n...         self.a = a\n...         self.b = b\n...         self.c = c\n...\n...         self.collector = Collector(get(self, 'a', 'b', 'c'))\n

\n
\n

You must pass an object and the names of attributes to `get()`. For each\nattribute, it generates a tuple `('attr', lambda: getattr(obj, 'attr'))` for\nyou.

\n
\n
\n

### Monitor many objects with one Collector\u00b6

\n

If you want to monitor the same attributes for many `Spam` instances with only\none Collector, there is another shortcut called `get_objects()` that works\nin a similar way:

\n

    >>> from collectors import get_objects\n>>> class Spam(object):\n...     def __init__(self, id):\n...         self.id = '_%d' % id\n...         self.a, self.b = 0, 0\n...\n>>> spams = [Spam(i) for i in range(10)]\n>>> collector = Collector(get_objects(spams, 'id', 'a', 'b'))\n

\n
\n

Similarly to `get()`, `get_objects()` creates a `(name, func)` tuple\nfor the attributes of all passed objects. In contrast to `get()` you must\nalso define an `id` attribute which will be prefixed to each name in order\nto make them distinguishable. Since the names become attributes of the Collector\ninstance, they must not be pure integers.

\n

In the above example, `collector` would have the attributes `_0_a`,\n`_0_b`, `_1_a` and so forth.

\n
\n
\n

### Manually passing values\u00b6

\n

Sometimes you might want to save some calculation results on-the-fly, were you\nwould use `lambda x: x` as a collector function. A shortcut for that is\n`manual()`:

\n

    >>> from collectors import Collector, manual\n>>> collector = Collector(('val', manual))\n>>> for i in range(10):\n...     collector(val=i)\n...\n>>> collector.val\n[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n

\n
\n
\n
\n

### Mixing shortcut functions\u00b6

\n

You can of course freely mix shortcut functions and \u201cnormal\u201d tuples:

\n

    >>> def foo():\n...     return spam.a + spam.b\n...\n>>> collector = Collector(\n...     ('foo', foo),\n...     ('bar', manual),\n...     get(spams[0], 'a', 'b'),\n...     get_objects(spams, 'id', 'a'),\n... )\n

\n
\n
\n
\n
\n

## What\u2019s next?\u00b6

\n

By default, `Collector` stores all collected values in\nplain Python lists, but it is also able to store them in various other formats\nlike PyTables/HDF5 or MS Excel. The next section\nexplains the various storage classes and how you can create your own.

\n
\n
\n", "display_toc": true, "title": "The Collector in-depth", "sourcename": "collector.txt", "current_page_name": "collector", "next": {"link": "../storages/", "title": "How to use the storage backends"}, "rellinks": [["genindex", "General Index", "I", "index"], ["modindex", "Global Module Index", "M", "modules"], ["storages", "How to use the storage backends", "N", "next"], ["quickstart", "Quickstart Guide", "P", "previous"]], "meta": {}, "parents": [], "toc": "

\n
- The Collector in-depth
  \n
  - How `Collector` works
    \n
    - Summary
    \n
    \n
  \n
  - Shortcut functions
    \n
    - Monitor several attributes of one object
    \n
    - Monitor many objects with one Collector
    \n
    - Manually passing values
    \n
    - Mixing shortcut functions
    \n
    \n
  \n
  - What\u2019s next?
  \n
  \n
\n

\n", "prev": {"link": "../quickstart/", "title": "Quickstart Guide"}, "metatags": ""}