Можете ли вы использовать типы LINQ и методы расширения в IronPython?

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

  •  06-07-2019
  •  | 
  •  

Вопрос

Можно ли использовать типы LINQ и методы расширения в IronPython?

Если так, то как? И также часто ли больше питонов, чтобы сделать то же самое?

Это было полезно?

Решение

IronPython 2.7, наконец, ликвидирует этот пробел с помощью метода clr.ImportExtensions , который добавляет методы расширения из пространства имен к целевым типам, например.

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

, что приводит его в соответствие с методом using_clr_extensions IronRuby 1.1.

Другие советы

Некоторые из вещей, которые вы бы делали с LINQ, могут быть выполнены с использованием списков:

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

Или вы можете использовать карту, уменьшить и фильтровать:

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

Но понимание списка гораздо более "Pythonic" чем использование функциональных конструкций программирования. Для сокращения расходов используйте " .join или sum . И вы можете проверить истинность значений целых итераций, используя любой и все

Просто запомните эти переводы:

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

И вы будете в пути!

В IronPython 2.7.1 у вас есть clr.ImportExtensions для этого варианта использования .

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)

Небольшая справка: IronPython 2.7 изначально представил эту функцию, но было an проблема , которая помешала его действительно использовать.

I описал класс-оболочку C # вокруг методов расширения LINQ для достижения синтаксиса, аналогичного синтаксису C # 'chained extension method' в IronPython.

Идея состоит в том, чтобы создать IEnumerable своего рода класс декоратора, который просто вызывает методы расширения. Возможно, этот класс-обёртка может быть написан так же хорошо в IronPython, но я еще не так хорошо разбираюсь в 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, ...

}

Это позволяет использовать синтаксис, подобный следующему:

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

Отказ от ответственности: это то, что я попробовал в качестве учебного упражнения, я не использовал это в реальном проекте.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top