Module containing some python utilities/abstractions python >= 3.7 compatible
python >= 3.7
pip install pytoolz
- Functional Ξ»
- Data Structures π
- Cache π
- Design π
- Logs π
- Multiprocess π―
- Serialization π€
A set of utilities oriented to functional programming.
Compose two functions: return the fn composition of the two
from pytoolz.functional import compose
if __name__ == "__main__":
f = compose(lambda x: x * 2,
lambda x: x * 3)
f(10)
# 60
Recursively apply a list of morphism to an input value
from pytoolz.functional import pipe
if __name__ == "__main__":
pipe([lambda x: x * 3,
lambda x: x * 2,
lambda x: x / 3], 10)
# 20.0
Apply the input function to every element in iterable and flatten the result list s
from pytoolz.functional import flat_map
if __name__ == "__main__":
flat_map(lambda x: [x, x], [1, 2, 3])
# [1, 1, 2, 2, 3, 3]
flat_map(lambda x: (x, x), [1, 2, 3])
# [1, 1, 2, 2, 3, 3]
Apply the input function to every element in iterable and flatten the result list lazily
from pytoolz.functional import iflat_map
if __name__ == "__main__":
iflat_map(lambda x: [x, x], [1, 2, 3])
# [1, 1, 2, 2, 3, 3]
iflat_map(lambda x: (x, x), [1, 2, 3])
# [1, 1, 2, 2, 3, 3]
Create side effect applying the input function for every element in iterable
from pytoolz.functional import iflat_map
if __name__ == "__main__":
iflat_map(lambda x: [x, x], [1, 2, 3])
# [1, 1, 2, 2, 3, 3]
iflat_map(lambda x: (x, x), [1, 2, 3])
# [1, 1, 2, 2, 3, 3]
[Experiment] Emulate the Java Stream API to create pipelines of transformations unsing function composition
from pytoolz.functional import Stream
if __name__ == "__main__":
Stream([1, 2, 3]).map(lambda x: x * 3).to_list()
# [3, 6, 9]
Stream([1, 2, 3]).sum().to_int()
# 6
Stream([1, 2, 3]).map(lambda x: x * 3).filter(lambda x: x >= 6).to_tuple()
# (6, 9)
Stream(["a", "b", "c"]).map(lambda x: x + "a").to_set() == {'aa', 'ba', 'ca'}
# True
Stream([1, 4, 3]) \
.map(lambda x: x + 3) \
.map(lambda x: x * x) \
.filter(lambda x: x > 3) \
.sum() \
.to_float()
# 101.0
#Alternative constructor
Stream.of([1, 2, 3], [
(Stream.map, lambda x: x * 3),
(Stream.map, lambda x: x * 3)
]).to_list()
# [9, 18, 27]
Serialization and deSerialization of objects: different engine are built-in: Json/Pickle/Dict
from pytoolz.serialization import Dict, Json, Pickle
if __name__ == "__main__":
original = '{"users": ["bob", "foo", "bar"], "companies": {}}'
data = Json(original).deserialize()
print(type(data))
# '<class 'dict'>'
string_data = Json(data).serialize()
print(type(string_data))
# '<class 'str'>'
Utilities related to data structures (missing data structures or customization of existing ones)
from pytooolz.ds import LinkedList, Node
if __name__ == "__main__":
ll = LinkedList()
ll.add(Node(3))
ll.add(Node(4))
ll.add(Node(5))
ll.add(Node(6))
print(ll)
#$ LinkedList(head=Node(value=6, next=Node(value=5, next=Node(value=4, next=Node(value=3, next=None)))))
TODO complete
Utilities related to caching. Different backend will be implemented: ex:
- Redis
- Memcache
- LRU in-memory
- Filesystem
from pytooolz.cache import memoize # memoize decorator
from pytooolz.cache import FileEngine # Disk cache engine
from pytooolz.cache import InMemoryEngine # LRU in memory engine
from pytooolz.cache import MemcachedEngine # Memcache engine
from pytooolz.cache import RedisEngine # Redis engine
if __name__ == "__main__":
@memoize(InMemoryEngine(limit=10, expiration=10))
def fn(*args):
return args
fn(1, 2, 3, 4, 5) # fn evaluated
fn(1, 2, 3, 4, 5) # got from cache
fn(1, 2, 3, 4, 5) # got from cache
fn(1, 2, 3, 4, 5) # got from cache
Utilities related to application design Singleton decorator - Examples:
from pytooolz.design import singleton
if __name__ == "__main__":
@singleton.singleton
class MyClass:
pass
assert id(MyClass()) == id(MyClass())
Traits Attach a specific trait to an instance. This should enable polimorphism using composition instead of classic inheritance
To use this feature:
- decorate your class with
@extendable
decorator - implement your custom class that implements
Trait
interface - choose one (or more) traits during the class init using
.with_trait(...)
Example:
from pytooolz.design import Trait
from pytooolz.design import extendable
if __name__ == "__main__":
class UserRenderHtml(Trait):
def render(self):
print("""
<h1>{0!s}</h1>
<p>{1!s}</p>
""".format(self.name, self.surname))
class UserRenderText(Trait):
def render(self):
print(self.name, self.surname)
@extendable
class User:
def __init__(self, name, surname):
self.name = name
self.surname = surname
usr = User("Andrea", "La Scola").with_trait(UserRenderHtml)
print(usr.render())
log decorators - multiple backends
- Andrea La Scola - Initial work - PurpleBooth