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

StackOverflow https://stackoverflow.com/questions/628482

  •  06-07-2019
  •  | 
  •  

Question

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

Si oui comment? Et aussi y a-t-il souvent plus de pythonique à faire la même chose?

Était-ce utile?

La solution

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 de 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 l'aligne sur la méthode using_clr_extensions d'IronRuby 1.1.

Autres conseils

Certaines choses que vous feriez avec LINQ peuvent être faites avec des listes compréhensives:

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

Vous pouvez également utiliser les fonctions mapper, réduire et filtrer:

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

Mais la compréhension de la liste est beaucoup plus "Pythonique". que d'utiliser les constructions de programmation fonctionnelle. Pour réduire les coûts, envisagez d’utiliser "forte" .join ou somme . Et vous pouvez vérifier la valeur de vérité d'itérables entiers en utilisant any et all

.

Rappelez-vous simplement ces traductions:

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

Et vous serez bien sur votre chemin!

Dans IronPython 2.7.1 , vous avez 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’arrière-plan: IronPython 2.7 avait initialement introduit cette fonctionnalité, mais il existait un problème qui l'empêchait d'être vraiment utilisable.

I a décrit une classe wrapper C # autour des méthodes d’extension LINQ afin d’obtenir une syntaxe similaire à la syntaxe 'Méthode chaînée d’extension' de C # dans IronPython.

L’idée est d’avoir une sorte de classe de décorateur autour de IEnumerable qui appelle simplement les méthodes d’extension. Probablement cette classe wrapper peut être écrite aussi bien dans IronPython, mais je ne maîtrise pas encore couramment le 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, ...

}

Ceci permet une syntaxe similaire à celle-ci:

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

Avertissement: c’est quelque chose que j’ai essayé en tant qu’exercice d’apprentissage, je ne l’ai pas utilisé dans un projet réel.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top