Skip to main content

weakget - Chain multiple `getattr` and `.get` calls into one expression

Project description

weakget - Chaining getattr and .get

With weakget, you can write code like:

x = weakget(obj)[5]['key'].attr.method() % 'default'

and x will be set to 'default' if:

  • obj has just 3 items, or
  • obj[5] is missing 'key', or
  • obj[5]['key'] doesn't have attr, or
  • obj[5]['key'].attr didn't define method()

Otherwise, x gets set to obj[5]['key'].attr.method(). Similar code in pure Python would look like:

try:
  x = obj[5]['key'].attr.method()
except (LookupError, AttributeError):
  x = 'default'

weakget is better because:

  • it doesn't hide AttributeError raised from obj[5] or obj[5]['key']
  • it doesn't hide LookupError raised from obj[5]['key'].attr or obj[5]['key'].attr.method
  • it doesn't hide any exception raised from calling obj[5]['key'].attr.method()
  • it fits on one line!

Usage

Install from PyPI using pip:

pip install weakget

Then import into your scripts:

>>> from weakget import weakget
>>> obj = []
>>> weakget(obj)[5]['key'].attr.method() % 'default'
'default'

pep505 - None-aware operations à la PEP 505

But wait, there's more! PEP 505 describes adding None-aware operators to Python, but you can get that behaviour today from pep505:

from weakget import pep505
x = pep505(a.attr, b.attr) % 3    # i.e. a.attr ?? b.attr ?? 3
y = pep505(c)['key'].attr % None  # i.e. c?.['key']?.attr

Behind-the-scenes, pep505 works in much the same way as weakget, but where weakget looks for LookupError or AttributeError to be raised, pep505 only looks for None. Similar code in pure Python would look like:

x = a.attr if a.attr is not None else b.attr if b.attr is not None else 3
y = c['key'].attr if (c is not None and c['key'] is not None) else None

pep505 is better because:

  • a.attr, b.attr, and c['key'] are each evaluated at most once
  • less typing, which also means...
  • less chance for logic errors

FAQs

Q: Why not use getattr's default instead of catching, and possibly hiding, AttributeErrors?

A: Turns out getattr also catches AttributeError:

>>> class A:
...   @property
...   def b(self):
...     return None.badattr
>>> getattr(A(), 'b')
AttributeError: 'NoneType' object has no attribute 'badattr'
>>> getattr(A(), 'b', 'default')
'default'

Q: Why not use .get's default argument instead of catching LookupError?

A: .get is implemented on mapping objects like dict, but is not available on sequence objects like list. Catching the LookupError from obj[key] is the only way to support both.

Q: Why % instead of or, |, or a method?

A: or isn't an option as it cannot be directly overloaded. | is enticing as a | b reads like "a or b", but "or" in Python usually refers to truthiness, which does not distinguish "lack of value" from "false". Adding a method would hide any method of the same name in the underlying object. % is already overloaded in Python, making it the best option among the remaining operators.

Q: Can't you come up with a better name than pep505?

A: Well, PP is currently in the lead as it looks like ??, but I'm open to suggestions!

Project details


Release history Release notifications | RSS feed

This version

1.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

weakget-1.0.tar.gz (8.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

weakget-1.0-py2.py3-none-any.whl (4.9 kB view details)

Uploaded Python 2Python 3

File details

Details for the file weakget-1.0.tar.gz.

File metadata

  • Download URL: weakget-1.0.tar.gz
  • Upload date:
  • Size: 8.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.28.1

File hashes

Hashes for weakget-1.0.tar.gz
Algorithm Hash digest
SHA256 f567d703af740d45331596a417ad6074c267a95842204b2084ddf2f8e83b6cac
MD5 18b6f93d6214c6ee18d855b0f7d26b57
BLAKE2b-256 a6c925d03c5377218cfd7030188f7a5c4e20e22030e3213a418958023558d1ca

See more details on using hashes here.

File details

Details for the file weakget-1.0-py2.py3-none-any.whl.

File metadata

  • Download URL: weakget-1.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 4.9 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-requests/2.28.1

File hashes

Hashes for weakget-1.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 ace5c9a9d2c713c827e10df656c2b12e7f2e85238b8e1d4386c1b9e2d68d06f8
MD5 56cab7678f5aab85ca7bb2c61afa8ae4
BLAKE2b-256 b0a7ce45ee606c97351c517a3d8f77d14c273c3b03325350779b539778bbe7f0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page