使用类似于元组的对象来模拟Python S表达式。
项目描述
etuples
使用类似于元组的对象来模拟Python S表达式。
示例
etuple
就像元组
>>> from operator import add
>>> from etuples import etuple, etuplize
>>> et = etuple(add, 1, 2)
>>> et
ExpressionTuple((<built-in function add>, 1, 2))
>>> from IPython.lib.pretty import pprint
>>> pprint(et)
e(<function _operator.add(a, b, /)>, 1, 2)
>>> et[0:2]
ExpressionTuple((<built-in function add>, 1))
etuple
也可以被评估
>>> et.evaled_obj
3
已评估的etuple
会被缓存
>>> et = etuple(add, "a", "b")
>>> et.evaled_obj
'ab'
>>> et.evaled_obj is et.evaled_obj
True
重建的etuple
及其评估结果会在元组操作间保持
>>> et_new = (et[0],) + et[1:]
>>> et_new is et
True
>>> et_new.evaled_obj is et.evaled_obj
True
rator
、rands
和apply
会返回操作符、操作数并将操作应用于操作数
>>> from etuples import rator, rands, apply
>>> et = etuple(add, 1, 2)
>>> rator(et)
<built-in function add>
>>> rands(et)
ExpressionTuple((1, 2))
>>> apply(rator(et), rands(et))
3
rator
和rands
是multipledispatch
函数,可以扩展以处理任意对象
from etuples.core import ExpressionTuple
from collections.abc import Sequence
class Node:
def __init__(self, rator, rands):
self.rator, self.rands = rator, rands
def __eq__(self, other):
return self.rator == other.rator and self.rands == other.rands
class Operator:
def __init__(self, op_name):
self.op_name = op_name
def __call__(self, *args):
return Node(Operator(self.op_name), args)
def __repr__(self):
return self.op_name
def __eq__(self, other):
return self.op_name == other.op_name
rands.add((Node,), lambda x: x.rands)
rator.add((Node,), lambda x: x.rator)
@apply.register(Operator, (Sequence, ExpressionTuple))
def apply_Operator(rator, rands):
return Node(rator, rands)
>>> mul_op, add_op = Operator("*"), Operator("+")
>>> mul_node = Node(mul_op, [1, 2])
>>> add_node = Node(add_op, [mul_node, 3])
etuplize
会将非元组对象转换为相应的etuple
形式
>>> et = etuplize(add_node)
>>> pprint(et)
e(+, e(*, 1, 2), 3)
>>> et.evaled_obj is add_node
True
etuplize
还可以进行浅对象到etuple
的转换
>>> et = etuplize(add_node, shallow=True)
>>> pprint(et)
e(+, <__main__.Node at 0x7f347361a080>, 3)
安装
使用pip
pip install etuples
开发
首先获取项目源代码
git clone git@github.com:pythological/etuples.git
创建虚拟环境并安装开发依赖项
$ pip install -r requirements.txt
设置pre-commit
钩子
$ pre-commit install --install-hooks
可以使用提供的Makefile
运行测试
make check