Skip to content

Latest commit

 

History

History
140 lines (109 loc) · 3.33 KB

stdlib_examples.md

File metadata and controls

140 lines (109 loc) · 3.33 KB

Situations where increments may be useful

This list shows situations where increments (if used with care) may allow to avoid repetitions or make code more readable. Each situation is demonstrated by an example of the code from the Python's standard library to ensure that this situation is realistic (this approach is inspired by the "Importance of real code" section of PEP 572 "Assignment Expressions"). Only one example is shown for clarity, however the standard library typically contains many similar examples.

By providing this list, I do not claim that using increments and/or allowing them makes Python code better in general. See the description of possible risks here.

1. if conditions

  • Source: multiprocessing/managers.py

    Current:

    self.id_to_refcount[ident] -= 1
    if self.id_to_refcount[ident] == 0:
        del self.id_to_refcount[ident]

    Improved:

    if --self.id_to_refcount[ident] == 0:
        del self.id_to_refcount[ident]

    This allows to avoid repeating the long subscription expression.

2. while conditions

  • Source: unittest/util.py

    Current:

    e = expected[i]
    a = actual[j]
    if e < a:
        missing.append(e)
        i += 1
        while expected[i] == e:
            i += 1
    elif e > a:
        unexpected.append(a)
        j += 1
        while actual[j] == a:
            j += 1
    else:
        i += 1
        try:
            while expected[i] == e:
                i += 1
        finally:
            j += 1
            while actual[j] == a:
                j += 1

    Improved:

    e = expected[i]
    a = actual[j]
    if e < a:
        missing.append(e)
        while expected[++i] == e:
            pass
    elif e > a:
        unexpected.append(a)
        while actual[++j] == a:
            pass
    else:
        try:
            while expected[++i] == e:
                pass
        finally:
            while actual[++j] == a:
                pass

    This allows to make code much shorter.

3. Incrementing callbacks

  • Source: test/test_weakref.py

    Current:

    def callback(w):
        self.cbcalled += 1
    
    o = C()
    r1 = MyRef(o, callback)
    r1.o = o
    del o

    Improved:

    o = C()
    r1 = MyRef(o, lambda: ++self.cbcalled)
    r1.o = o
    del o

    This allows to avoid the full function definition in a separate place.

4. Handmade enums

  • Source: distutils/log.py

    Current:

    DEBUG = 1
    INFO = 2
    WARN = 3
    ERROR = 4
    FATAL = 5

    Improved:

    _index = 0
    DEBUG = ++_index
    INFO = ++_index
    WARN = ++_index
    ERROR = ++_index
    FATAL = ++_index

    This makes adding new values and reordering the existing ones easier.