2009-03-09 16 views
34

Có thể sử dụng các kiểu LINQ và các phương thức mở rộng trong IronPython không?Bạn có thể sử dụng các loại LINQ và các phương thức mở rộng trong IronPython không?

Nếu có thì làm cách nào? Và cũng thường có nhiều chất pythonic hơn để làm điều tương tự?

+0

Ólafur, vui lòng chọn câu trả lời của Steve Gilham để mọi người duyệt qua câu hỏi này xem thông tin chính xác cập nhật. Tại 50K, tôi không nghĩ rằng John Feminella sẽ bỏ lỡ đại diện. –

Trả lời

41

IronPython 2.7 cuối cùng sẽ thu hẹp khoảng cách này với phương thức clr.ImportExtensions, thêm phương thức mở rộng từ không gian tên vào các loại mục tiêu, ví dụ:

>& '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__'] 
>>> 

để nó phù hợp với phương pháp IronRuby 1.1 using_clr_extensions.

23

Một số trong những điều bạn muốn làm với LINQ có thể được thực hiện với comprehensions danh sách:

[myFunc(i) for i in numbers if i > 3] 

Hoặc bạn có thể sử dụng bản đồ, giảm, và lọc:

map(myFunc, filter(lambda x: x > 3, numbers)) 

Nhưng danh sách comprehensions là nhiều hơn "Pythonic" hơn là sử dụng các cấu trúc lập trình hàm. Để giảm sự vật, hãy xem xét sử dụng "" .join hoặc tổng số. Và bạn có thể kiểm tra giá trị chân lý của toàn bộ iterables bằng cách sử dụng bất kỳ tất cả

Chỉ cần nhớ những bản dịch:

Select -> map 
Where -> filter 
Aggregate -> reduce 

và bạn sẽ được tốt trên con đường của bạn!

+3

cũng vậy, set() là một sự thay thế tốt cho Distinct() – Phil

3

I described a C# wrapper class xung quanh các phương pháp mở rộng LINQ để đạt được cú pháp tương tự cú pháp phương pháp mở rộng 'chuỗi' của C# trong IronPython.

Ý tưởng là có một loại lớp trang trí quanh IEnumerable chỉ đơn giản là gọi các phương thức mở rộng. Có lẽ lớp wrapper này có thể được viết giống như tốt trong IronPython, nhưng tôi không phải là thông thạo python chưa :-)

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, ... 

} 

Điều này cho phép một cú pháp tương tự như sau:

johns = ToLinq[Customer](customers)\ 
      .Where(lambda c: c.Name.StartsWith("John"))\ 
      .Select(lambda c: c.Name) 

Disclaimer : đây là một cái gì đó tôi đã cố gắng như là một tập thể dục học tập, tôi đã không được sử dụng trong một dự án thực tế.

11

Trong IronPython 2.7.1 bạn có clr.ImportExtensions cho trường hợp sử dụng này.

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) 

Một nền chút: IronPython 2.7 ban đầu giới thiệu tính năng này, nhưng đã có an issue mà dừng lại nó từ đang được thực sự sử dụng được.

Các vấn đề liên quan