35 votes

Pouvez-vous utiliser des types LINQ et des méthodes d'extension dans IronPython?

Est-il possible d'utiliser les types LINQ et les méthodes d'extension dans IronPython?

Si c'est le cas, comment? Et aussi y a-t-il souvent plus de pythonic pour faire la même chose?

44voto

Steve Gilham Points 7829

IronPython 2.7 comble enfin cet écart avec la méthode clr.ImportExtensions qui ajoute les méthodes d'extension d'un espace de noms aux types cibles, par exemple

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

ce qui le met en conformité avec la méthode using_clr_extensions d'IronRuby 1.1.

24voto

Patrick Points 20392

Certaines des choses que vous feriez avec LINQ peut être fait avec les interprétations de la liste:

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

Ou vous pouvez utiliser la carte, de réduire et de filtre:

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

Mais les interprétations de la liste sont beaucoup plus "Pythonic" que d'utiliser les constructions de programmation fonctionnelle. Pour réduire les choses, de considérer l'utilisation de "".rejoindre ou de la somme. Et vous pouvez vérifier la valeur de vérité de toute iterables par l'aide de tout et de tous

Juste souvenez-vous de ces traductions:

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

Et vous serez bien sur votre chemin!

16voto

Simon Opelt Points 2452

Dans IronPython 2.7.1, vous disposez de clr.ImportExtensions pour ce cas d'utilisation.

 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)
 

Un peu d'histoire: IronPython 2.7 a initialement introduit cette fonctionnalité, mais il y avait un problème qui l'empêchait d'être vraiment utilisable.

3voto

jeroenh Points 12777

J'ai décrit un C# classe wrapper autour de l'extension LINQ méthodes pour parvenir à une syntaxe similaire à C#'s 'enchaînés méthode d'extension' la syntaxe dans IronPython.

L'idée est d'avoir une sorte de décorateur de classe autour de l' IEnumerable qui appelle simplement les méthodes d'extension. Probablement cette classe wrapper peut être écrite aussi bien dans IronPython, mais je ne suis pas aussi à l'aise en python encore :-)

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

}

Cela permet une syntaxe similaire à ceci:

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

Avertissement: ce est quelque chose que j'ai essayé de l'apprentissage d'excercice, je n'ai pas utilisé ce dans un projet du monde réel.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X