一款花哨实用的功能工具
项目描述
一系列注重实用性的精美功能工具。
受到 clojure、underscore 和我自己的抽象的启发。继续阅读以获得概述或阅读文档。或者直接跳到备忘单。
适用于 Python 2.7、3.4+ 和 pypy。
安装
pip install funcy
概述
从 funcy 导入东西以使事情发生:
from funcy import whatever, you, need
合并相同类型的集合(适用于字典、集合、列表、元组、迭代器甚至字符串):
merge(coll1, coll2, coll3, ...)
join(colls)
merge_with(sum, dict1, dict2, ...)
遍历集合,创建它的变换(像 map 但保留类型):
walk(str.upper, {'a', 'b'}) # {'A', 'B'}
walk(reversed, {'a': 1, 'b': 2}) # {1: 'a', 2: 'b'}
walk_keys(double, {'a': 1, 'b': 2}) # {'aa': 1, 'bb': 2}
walk_values(inc, {'a': 1, 'b': 2}) # {'a': 2, 'b': 3}
选择集合的一部分:
select(even, {1,2,3,10,20}) # {2,10,20}
select(r'^a', ('a','b','ab','ba')) # ('a','ab')
select_keys(callable, {str: '', None: None}) # {str: ''}
compact({2, None, 1, 0}) # {1,2}
操作序列:
take(4, iterate(double, 1)) # [1, 2, 4, 8]
first(drop(3, count(10))) # 13
lremove(even, [1, 2, 3]) # [1, 3]
lconcat([1, 2], [5, 6]) # [1, 2, 5, 6]
lcat(map(range, range(4))) # [0, 0, 1, 0, 1, 2]
lmapcat(range, range(4)) # same
flatten(nested_structure) # flat iter
distinct('abacbdd') # iter('abcd')
lsplit(odd, range(5)) # ([1, 3], [0, 2, 4])
lsplit_at(2, range(5)) # ([0, 1], [2, 3, 4])
group_by(mod3, range(5)) # {0: [0, 3], 1: [1, 4], 2: [2]}
lpartition(2, range(5)) # [[0, 1], [2, 3]]
chunks(2, range(5)) # iter: [0, 1], [2, 3], [4]
pairwise(range(5)) # iter: [0, 1], [1, 2], ...
和功能:
partial(add, 1) # inc
curry(add)(1)(2) # 3
compose(inc, double)(10) # 21
complement(even) # odd
all_fn(isa(int), even) # is_even_int
one_third = rpartial(operator.div, 3.0)
has_suffix = rcurry(str.endswith, 2)
轻松创建装饰器:
@decorator
def log(call):
print call._func.__name__, call._args
return call()
抽象控制流:
walk_values(silent(int), {'a': '1', 'b': 'no'})
# => {'a': 1, 'b': None}
@once
def initialize():
"..."
with suppress(OSError):
os.remove('some.file')
@ignore(ErrorRateExceeded)
@limit_error_rate(fails=5, timeout=60)
@retry(tries=2, errors=(HttpError, ServiceDown))
def some_unreliable_action(...):
"..."
class MyUser(AbstractBaseUser):
@cached_property
def public_phones(self):
return self.phones.filter(public=True)
轻松调试:
squares = {tap(x, 'x'): tap(x * x, 'x^2') for x in [3, 4]}
# x: 3
# x^2: 9
# ...
@print_exits
def some_func(...):
"..."
@log_calls(log.info, errors=False)
@log_errors(log.exception)
def some_suspicious_function(...):
"..."
with print_durations('Creating models'):
Model.objects.create(...)
# ...
# 10.2 ms in Creating models
还有更多。
潜入
Funcy 是我在几篇文章中解释的想法的体现:
运行测试
使用您的默认 python 运行测试:
pip install -r test_requirements.txt py.test
要完全运行tox,您需要安装所有受支持的 python。这些是 2.6+、3.3+、PyPy 和 PyPy3。即使没有上述所有条件,您也可以在特定环境中运行它:
tox -e py27 tox -e py36 tox -e lint