你可以在IronPython中使用LINQtypes和扩展方法吗?
是否有可能在IronPython中使用LINQtypes和扩展方法?
如果这样怎么样? 同样的事情也经常有更多的pythonic?
IronPython 2.7最终通过clr.ImportExtensions
方法弥补了这个clr.ImportExtensions
,该方法将扩展方法从命名空间添加到目标types,例如
>& 'C:\Program Files\IronPython 2.7\ipy.exe' IronPython 2.7 (2.7.0.40) on .NET 4.0.30319.225 Type "help", "copyright", "credits" or "license" for more information. >>> import clr >>> clr.AddReference("System.Core") >>> from System.Collections.Generic import List >>> dir (List) ['Add', 'AddRange', 'AsReadOnly', 'BinarySearch', 'Capacity', 'Clear', 'Contains', 'ConvertAll', 'CopyTo', 'Count', 'Enu merator', 'Equals', 'Exists', 'Find', 'FindAll', 'FindIndex', 'FindLast', 'FindLastIndex', 'ForEach', 'GetEnumerator', ' GetHashCode', 'GetRange', 'GetType', 'IndexOf', 'Insert', 'InsertRange', 'IsReadOnly', 'IsSynchronized', 'Item', 'LastIn dexOf', 'MemberwiseClone', 'ReferenceEquals', 'Remove', 'RemoveAll', 'RemoveAt', 'RemoveRange', 'Reverse', 'Sort', 'Sync Root', 'ToArray', 'ToString', 'TrimExcess', 'TrueForAll', '__add__', '__class__', '__contains__', '__delattr__', '__doc_ _', '__format__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__iter__', '__len__', '__new__', '__reduce __', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__'] >>> import System >>> clr.ImportExtensions(System.Linq) >>> dir (List) ['Add', 'AddRange', 'Aggregate', 'All', 'Any', 'AsEnumerable', 'AsParallel', 'AsQueryable', 'AsReadOnly', 'Average', 'Bi narySearch', 'Capacity', 'Cast', 'Clear', 'Concat', 'Contains', 'ConvertAll', 'CopyTo', 'Count', 'DefaultIfEmpty', 'Dist inct', 'ElementAt', 'ElementAtOrDefault', 'Enumerator', 'Equals', 'Except', 'Exists', 'Find', 'FindAll', 'FindIndex', 'F indLast', 'FindLastIndex', 'First', 'FirstOrDefault', 'ForEach', 'GetEnumerator', 'GetHashCode', 'GetRange', 'GetType', 'GroupBy', 'GroupJoin', 'IndexOf', 'Insert', 'InsertRange', 'Intersect', 'IsReadOnly', 'IsSynchronized', 'Item', 'Join', 'Last', 'LastIndexOf', 'LastOrDefault', 'LongCount', 'Max', 'MemberwiseClone', 'Min', 'OfType', 'OrderBy', 'OrderByDesc ending', 'ReferenceEquals', 'Remove', 'RemoveAll', 'RemoveAt', 'RemoveRange', 'Reverse', 'Select', 'SelectMany', 'Sequen ceEqual', 'Single', 'SingleOrDefault', 'Skip', 'SkipWhile', 'Sort', 'Sum', 'SyncRoot', 'Take', 'TakeWhile', 'ToArray', ' ToDictionary', 'ToList', 'ToLookup', 'ToString', 'TrimExcess', 'TrueForAll', 'Union', 'Where', 'Zip', '__add__', '__clas s__', '__contains__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__hash__', '__init__', '__iter__', '__len__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__' , '__str__', '__subclasshook__'] >>>
这使它与IronRuby 1.1的using_clr_extensions
方法一致。
你可以用列表parsing来完成一些你用LINQ做的事情:
[myFunc(i) for i in numbers if i > 3]
或者你可以使用map,reduce和filter:
map(myFunc, filter(lambda x: x > 3, numbers))
但是列表理解要比使用函数式编程结构更“Pythonic”。 为了减less事情,考虑使用“” 。join或总和 。 你可以使用任何和所有的方法来检查整个迭代的真值
只要记住这些翻译:
Select -> map Where -> filter Aggregate -> reduce
你会很好的在路上!
在IronPython 2.7.1中,你有这个用例的clr.ImportExtensions 。
import clr clr.AddReference("System.Core") import System clr.ImportExtensions(System.Linq) # will print 3 and 4 :) [2, 3, 4].Where(lambda x: x != 2).ToList().ForEach(System.Console.WriteLine)
一个小小的背景: IronPython 2.7最初引入了这个特性,但是有一个问题阻止了它真的可用。
我描述了一个围绕LINQ扩展方法的C#包装类 ,以实现类似于IronPython中C#的“链式扩展方法”语法的语法。
这个想法是IEnumerable
周围有一种装饰类,只是简单地调用扩展方法。 也许这个包装类可以写在IronPython中,但是我还不是很stream利的python呢:-)
public class ToLinq<T> : IEnumerable<T> { private readonly IEnumerable<T> _wrapped; public ToLinq(IEnumerable<T> wrapped) { _wrapped = wrapped; } public ToLinq<T> Where(Func<T, bool> predicate) { return new ToLinq<T>(_wrapped.Where(predicate)); } // ... similar methods for other operators like Select, Count, Any, ... }
这允许一个类似于这样的语法:
johns = ToLinq[Customer](customers)\ .Where(lambda c: c.Name.StartsWith("John"))\ .Select(lambda c: c.Name)
免责声明:这是我尝试作为一个学习练习,我没有在一个现实世界的项目中使用这个。