Kann die Idee von LINQ in C # in Maya Python verwendet werden? Ich versuchte es herauszufinden.
――Ich möchte die Liste einfacher und einfacher bedienen. ――Wenn Sie etwas Ähnliches wie C # schreiben können, sollten die Umstellungskosten sinken.
Ich werde die Erklärung zu LINQ anderen Websites überlassen (Referenzseiten sind am Ende der Seite zusammengefasst). Grob gesagt ist es "* eine Funktion zum Filtern und Verarbeiten von Werten in einer SQL-Anweisung-ähnlichen Weise für Listen usw. *". Der Code, der tatsächlich LINQ verwendet, lautet wie folgt.
LinqSample.cs
var hoge = new int[] { 0, 1, 2, 3, 4, 5 };
var hogehoge = hoge.where(n => n > 3).select(n => n * n);
foreach (var x in hogehoge)
Debug.WriteLine(x);
>>> 16
>>> 25
Wenn Sie den obigen Code in Pythons ** Listeneinschlussnotation ** schreiben, ist dies wie folgt.
list_comprehension_sample.py
hoge = [0, 1, 2, 3, 4, 5]
hogehoge = [x * x for x in hoge if x > 3]
for x in hogehoge:
print x
>>> 16
>>> 25
Wenn Sie es so schreiben, wäre es meiner Meinung nach schön, wenn es eine Listeneinschlussnotation gäbe. (Ryuishi Python) Da Slices in Python verwendet werden können, gibt es außerdem nur wenige Probleme mit Listenoperationen.
Die Funktionen von LINQ umfassen ** Methodenkette ** und ** Verzögerungsbewertung **. Ich denke, der große Vorteil ist, dass es leicht zu verstehen und zu schreiben ist, während der Code einfach gekürzt wird. Das Schreiben komplexer Operationen mit Python-Listeneinschlüssen und Slices kann erheblich weniger lesbar sein.
Aufgrund dieser Situation habe ich darüber nachgedacht, wie die guten Teile von LINQ reproduziert werden können.
Zuerst habe ich versucht, nur die Schnittstelle so zu gestalten, um die Atmosphäre zu überprüfen. Der erste Versuch besteht darin, dieselbe Methode wie LINQ vorzubereiten und nur den einzelnen Effekt näher zu bringen.
iterator_v1.py
class GeneralIterator(object):
"""Eine Klasse, die Listenoperationen mit LINQ-Methodennamen umschließt
<usage>
selection = GeneralIterator(cmds.ls(sl=True))
selection.count()
for x in selection.generator(): print x
selection.last()
selection.first()
selection.at(3)
selection.distinct()
selection.skip(3)
selection.take(3)
selection.all(lambda x: x.startswith('mesh_'))
selection.any(lambda x: x.startswith('skel_'))
selection.contains("grp_")
selection.union(["group1", "group2"])
selection.reverse()
selection.select(lambda x: cmds.getAttr(x + '.tx'))
selection.where(lambda x: x.endswith('_offset'))
"""
def __init__(self, list=None):
self.set_list(list)
def set_list(self, list):
self.__list = list
def is_empty(self):
return self.__list is None or len(self.__list) == 0
def print_items(self):
for x in self.generator():
print x
def count(self):
if self.is_empty():
return 0
return len(self.__list)
def generator(self):
for x in self.__list:
yield x
def first(self, default=None):
if self.is_empty():
return default
return self.__list[0]
def last(self, default=None):
if self.is_empty():
return default
return self.__list[-1]
def at(self, index, default=None):
if index <= self.count():
return self.__list[index]
return default
def distinct(self):
return list(set(self.__list))
def skip(self, count):
if count < self.count():
return self.__list[count:]
def take(self, count):
if count <= self.count():
return self.__list[:count]
def all(self, func):
for x in self.generator():
if not func(x):
return False
return True
def any(self, func):
for x in self.generator():
if func(x):
return True
return False
def contains(self, obj):
for x in self.generator():
if x == obj:
return True
return False
def union(self, list):
return self.__list + list
def reverse(self):
return list(reversed(self.__list))
def select(self, func):
return [func(x) for x in self.__list]
def where(self, func):
return [x for x in self.__list if func(x)]
Als nächsten Schritt möchte ich eine Methodenkette. Ich würde gerne eine verspätete Ausführung sehen. Nachdem ich die Implementierungsmethode von LINQ gelesen hatte, dachte ich, dass ich mit dem Verschluss etwas Ähnliches machen könnte, und versuchte es mit der zweiten.
iterator_v2.py
class EnumerableIterator(object):
"""Listen Sie die Manipulationsklasse auf, die Methodenkette und verzögerte Ausführung wie LINQ ausprobiert hat
[usage]
hoge = EnumerableIterator(range(10))
for x in hoge.where(lambda x: x > 7).select(lambda x: x * x): print x
"""
def __init__(self, list=None, func=None):
self._set_list(list)
self.func = func
def _set_list(self, list):
self.__list = list
def __execute_func(self):
if self.func is None:
return self.__list
return self.func(self.__list)
def __iter__(self):
for x in self.__execute_func():
yield x
def to_list(self):
return self.__execute_func()
def count(self):
return len(self.__execute_func())
def __is_empty(self, list):
return list is None or len(list) == 0
def first(self, default=None):
result = self.__execute_func()
if self.__is_empty(result):
return default
return result[0]
def last(self, default=None):
result = self.__execute_func()
if self.__is_empty(result):
return default
return result[-1]
def at(self, index, default=None):
result = self.__execute_func()
if self.__is_empty(result):
return default
if index <= len(result):
return list[index]
return default
def distinct(self):
return list(set(self.__execute_func()))
def skip(self, count):
result = self.__execute_func()
return result[count:]
def take(self, count):
result = self.__execute_func()
return result[:count]
def all(self, func):
for x in self:
if not func(x):
return False
return True
def any(self, func):
for x in self:
if func(x):
return True
return False
def contains(self, obj):
for x in self:
if x == obj:
return True
return False
def union(self, list):
return self.__execute_func() + list
def reverse(self):
return list(reversed(self.__execute_func()))
def where(self, func):
def action(list):
result = list
if self.func is not None:
result = self.func(list)
return [x for x in result if func(x)]
return EnumerableIterator(self.__list, action)
def select(self, func):
def action(list):
result = list
if self.func is not None:
result = self.func(list)
return [func(x) for x in result]
return EnumerableIterator(self.__list, action)
Wenn nichts unternommen wird, wird der Inhalt nicht mit Maya in Verbindung gebracht, daher werde ich versuchen, ihn in Maya zu verwenden.
iterator_v2.py
class EnumerableSelection(EnumerableIterator):
"""Objektauswahl-Iterator
[usage]
selection = Selection()
for x in selection.where(lambda x: x.endswith('_offset')).select(lambda x: cmds.getAttr(x + '.tx')):
print x
print selection \
.where(lambda x: x.endswith('Group')) \
.select(lambda x: cmds.getAttr(x + '.tx')) \
.where(lambda x: x > 0.1) \
.first()
"""
def __init__(self, flat=True):
super(EnumerableSelection, self).__init__()
self.__flat = flat
self.update()
def update(self):
self._set_list(cmds.ls(sl=True, fl=self.__flat))
Es gibt auch itertools und mehr-itertools, aber ich bevorzuge LINQ als Schreibstil. Ich habe das Gefühl, dass ich im pythonischen Stil schreiben kann, wenn ich die Sprachspezifikationen besser verstehen und verwenden kann. Ich möchte weiter studieren und auf Ratschläge und Ratschläge aus verschiedenen Bereichen warten.
Recommended Posts