2009-03-09 7 views
34

Ist es möglich, die LINQ-Typen und Erweiterungs-Methoden in IronPython zu verwenden?Können Sie in IronPython LINQ-Typen und Erweiterungsmethoden verwenden?

Wenn ja wie? Und gibt es auch oft mehr Python, um das Gleiche zu tun?

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

Oder Sie können Karte verwenden, reduzieren und Filter:

+0

Ólafur, bitte wählen Sie Steve Gilhams Antwort, damit die Leute, die zu dieser Frage navigieren, aktuelle, korrekte Informationen sehen. Bei 50K glaube ich nicht, dass John Feminella die Wiederholung verpassen wird. –

Antwort

41

IronPython 2.7 schließlich schließt diese Lücke mit der clr.ImportExtensions-Methode, die die Erweiterungsmethoden aus einem Namespace den Zieltypen hinzufügt, z.

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

, die sie in Einklang mit IronRuby 1.1 des using_clr_extensions Methode bringt.

23

Einige der Dinge, die Sie mit LINQ tun würde, kann mit Listenkomprehensionen erfolgen

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

Aber Listenkomprehensionen sind viel mehr "Pythonic" als die Verwendung der funktionalen Programmierkonstrukte. Verwenden Sie zur Reduzierung von Problemen die Verwendung von "" .join oder sum. Und Sie können den Wahrheitswert gesamten Iterables überprüfen, indem Sie mit jede und alle

Gerade diese Übersetzungen erinnern:

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

Und Sie werden auch auf Ihrem Weg!

+3

auch, set() ist ein guter Ersatz für Distinct() – Phil

3

I described a C# wrapper class um die LINQ-Extension-Methoden zu erreichen, um eine ähnliche Syntax wie in C# 'Chained Extension-Methode' -Syntax in IronPython zu erreichen.

Die Idee ist, eine Art Dekorator-Klasse um IEnumerable zu haben, die einfach die Erweiterungsmethoden aufruft. Wahrscheinlich kann diese Wrapper-Klasse genauso gut in Ironpython geschrieben werden, aber ich bin nicht so fließend in Python noch :-)

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

} 

Dies ermöglicht eine Syntax wie folgt aus:

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

Haftungsausschluss : Das ist etwas, was ich als Lernübung ausprobiert habe, ich habe das nicht in einem realen Projekt verwendet.

11

In IronPython 2.7.1 haben Sie clr.ImportExtensions für diesen Anwendungsfall.

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) 

Ein wenig Hintergrund: IronPython 2.7 zunächst diese Funktion eingeführt, aber es war an issue, die sie von wirklich verwendbar ist gestoppt.

Verwandte Themen