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?
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?
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.
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!
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.
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 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.