使用linq为对象样式方法扩展内置python集合
dontasq的Python项目详细描述
使用对象样式方法的linq扩展内置python集合
说明
库使用来自Robert Smallshire的asq的方法扩展内置的python集合。官方不允许向内置程序添加方法,但可以在cpython(2.x和3.x)中使用下面相应部分中描述的黑客来完成此操作。
例如:
>>>importdontasq>>>>>>[1,2,3].select_many(lambdax:(x,x**2)).to_tuple()(1,1,2,4,3,9)>>>'oh brave new world'.split() \ ....where(lambdaword:len(word)>=5) \ ....select(str.capitalize) \ ....to_list()['Brave','World']
在某些情况下,这种样式有助于编写比使用map、filter和生成器表达式的代码更清晰的函数式代码:不与括号混淆,方法按自然顺序应用。
警告!dontasq使用未记录的cpython功能。不能保证这些特性在将来的python版本中得到维护。
详细信息
在导入期间,dontasq在内置命名空间、collections和itertools模块中查找类。如果一个类是iterable,而不是元类,那么库会将asq.queryables.Queryable的所有公共方法附加到它,这样方法调用:
>>>instance.select(lambdax:x*2)
将等于:
>>>Queryable(instance).select(lambdax:x*2)
因此这些方法将被添加到诸如list、str、collections.OrderedDict或itertools.count之类的类中。您可以在asq documentation中找到所有Queryable方法及其说明的列表。
如果一个类已经包含一个同名的属性(例如str.join和list.count),则不会替换该属性。
当然,当使用dontasq:
>>>importdontasq>>>fromasq.predicatesimport*>>>>>>words=['banana','receive','believe','ticket','deceive']>>>words.where(contains_('ei')).to_list()['receive','deceive']
如果要修补另一个库中的类,可以使用方法dontasq.patch_type和dontasq.patch_module:
>>>importbintrees>>>importdontasq>>>>>>dontasq.patch_type(bintrees.AVLTree)>>>>>>dictionary={1:'Anton',2:'James',3:'Olivia'}>>>bintrees.AVLTree(dictionary).select(lambdax:x*2).to_list()[2,4,6]
您可以在“tests” directory中找到其他示例。
向内置项添加方法
在stackoverflow上的this question中可以找到以下方法。
正式地说,您只能获得内置'__dict__的受保护(只读)实例。诀窍在于,在cpython中,这个实例包含对原始(可修改)字典的引用,该字典可以使用gc.get_referents函数跟踪。
例如,我们可以将select方法添加到内置的list(与dontasq不同,在本例中它是非惰性的):
>>>importgc>>>gc.get_referents(vars(list))[0]['select']=lambdaself,func:list(map(func,self))>>>>>>[1,2,3].select(lambdax:x*2)[2,4,6]
另一种可能的方法是使用与ctypes.pythonapi模块交互的forbiddenfruit库。这两种方法在python 2和3上都能稳定地工作,但仅限于cpython。
安装
您可以使用pip安装库:
sudo pip install dontasq
或者安装以前下载和提取的软件包:
sudo python setup.py install