https://github.com/obriencj/python-mapbind
mapbind, a simple utility for binding vars from a map
https://github.com/obriencj/python-mapbind
python python2 python3
Last synced: about 1 year ago
JSON representation
mapbind, a simple utility for binding vars from a map
- Host: GitHub
- URL: https://github.com/obriencj/python-mapbind
- Owner: obriencj
- License: lgpl-3.0
- Created: 2017-09-14T18:07:46.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2024-09-04T12:46:41.000Z (over 1 year ago)
- Last Synced: 2025-03-18T23:18:38.684Z (about 1 year ago)
- Topics: python, python2, python3
- Language: Python
- Homepage:
- Size: 41 KB
- Stars: 3
- Watchers: 2
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Overview of python-mapbind
Functions that inspect their calling frame to figure out how you were
going to bind their results, and returns values appropriate for the
bindings.
## Wut?
A friend gave me the idea, and I wanted to see if it was possible.
Spoilers: it totally was.
## Usage
Consider the following
```python
# if you find yourself having to write code like this
a = data["a"]
b = data["b"]
c = data["c"]
# or like this
a, b, c = map(data.get, ("a", "b", "c"))
# then stop it. Use mapbind instead:
from mapbind import mapbind
a, b, c = mapbind(data)
```
The `mapbind` function looks at its calling frame's bytecode, figures
out that the result is going to be used in an unpacking assignment,
finds the names of the variables the assignment would bind to, and
returns an iterator for the values of the given items in data with
matching keys. Supercool.
Also included are `objbind` which will find attributes on an object,
`funbind` which will call a function for each binding name, and
`takebind` which will return the right amount of values from a
sequence to fulfill the count of bindings.
```python
from mapbind import objbind
# objbind will notice that its assignment is to the variables named "a",
# "b", and "c" and will subsequently fetch attributes with those names
# from some_object and return a 3-tuple of their values.
a, b, c = objbind(some_object)
assert a == some_object.a
assert b == some_object.b
assert c == some_object.c
```
```python
from mapbind import funbind
accu = []
def accumulator(name):
accu.append(name)
return "|%s|" % name
# funbind will notice that its assignment is to the variables named "a",
# "b", and "c" and will subsequently invoke accumulator with those strings
# in turn, returning a 3-tuple of their values.
a, b, c = funbind(accumulator)
assert accu == ["a", "b", "c"]
assert a == "|a|"
assert b == "|b|"
assert c == "|c|"
```
```python
from mapbind import takebind
# Even though a range is huge, takebind will snag exactly as many items
# from it as you're going to assign to.
seq = range(0, 100)
a, b = takebind(seq)
assert a == 0
assert b == 1
# And if you have too small of a range, you can tell takebind how you'd
# like it to pad out any missing assignments
seq = range(0, 2)
a, b, c, d, e, f, g = takebind(seq, 9001)
assert a == 0
assert b == 1
assert [c, d, e, f, g] == [9001] * 5
```
## But...
"Can't I just do `locals().update(data)`?"
That only works at the global/module scope. Once you're inside of a
function, `locals()` is nothing but a snapshot of the underlying fast,
free, and cell variables in a call frame.
## What Doesn't It Do
Mapbind's purpose is specific to unpacking for variable assignment.
Not for item assignment, not for member assignment. All of the
following will result in an exception being raised.
```python
# You only want one member? Then just get it directly, no need for
# mapbind. This is an error.
a = mapbind(my_data)
# this kind of nesting makes zero sense in the context of mapbind, so
# don't do it. If you do, it's an error.
a, (b, c) = mapbind(my_data)
# copying from one map to another is something you can do already, no
# need for mapbind, so this is an error.
x["a"], x["b"], x["c"] = mapbind(my_data)
# we don't support this because the assignment operations are
# interleaved with expressions to load their owning object.
x.a, y.b, z.c = mapbind(my_data)
```
It is trivial to write a function that will update a map or an
object's attributes from a map given a list of keys. There's no reason
for mapbind to support that use case. Mapbind is specifically for
situations where the list of keys can be determined entirely from the
storage variable names.
## Supported Versions
This has been tested as working on the following versions and
implementations of Python
* Python 2.6, 2.7
* Python 3.3, 3.4, 3.5, 3.6, 3.7
* PyPy, PyPy3
It is implemented entirely in Python (no native extensions). It has no
runtime dependencies outside of itself and those provided as part of
the standard Python environment, though to run the unit tests you'll
need setuptools.
## Contact
author: Christopher O'Brien
original git repository:
## License
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 3 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see
.