L'idée de LINQ en C # peut-elle être utilisée dans Maya Python? J'ai essayé de le découvrir.
――Je souhaite utiliser la liste plus facilement et plus facilement. ――Si vous pouvez écrire quelque chose de similaire à C #, le coût de commutation devrait baisser.
Je laisserai l'explication sur LINQ à d'autres sites (les sites de référence sont résumés en bas de page) En gros, c'est "* une fonction pour filtrer et traiter les valeurs d'une manière semblable à une instruction SQL pour les listes, etc. *". Le code qui utilise réellement LINQ est le suivant.
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
Si vous écrivez le code ci-dessus dans la ** notation d'inclusion de liste ** de Python, ce sera comme suit.
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
Si vous l'écrivez comme ceci, je pense que ce serait bien s'il y avait une notation d'inclusion de liste. (Ryuishi Python) De plus, comme les tranches peuvent être utilisées en Python, il y a peu de problèmes avec les opérations de liste.
Les fonctionnalités de LINQ incluent ** la chaîne de méthodes ** et ** l'évaluation du retard **. Je pense que le gros avantage est qu'il est facile à comprendre et à écrire tout en raccourcissant simplement le code. L'écriture d'opérations complexes avec des inclusions et des tranches de liste Python peut être beaucoup moins lisible.
Sur la base de cette situation, j'ai réfléchi à la façon de reproduire les bonnes parties de LINQ.
Tout d'abord, j'ai essayé de ne faire que l'interface comme ça pour vérifier l'atmosphère. Le premier essai consiste à préparer la même méthode que LINQ et à essayer de rapprocher uniquement l'effet unique.
iterator_v1.py
class GeneralIterator(object):
"""Une classe qui encapsule les opérations de liste à l'aide des noms de méthode LINQ
<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)]
Comme étape suivante, je veux une chaîne de méthodes. Je voudrais voir une exécution retardée. Après avoir lu la méthode d'implémentation de LINQ, j'ai pensé que je pourrais faire quelque chose de similaire en utilisant la fermeture, et j'ai essayé la seconde.
iterator_v2.py
class EnumerableIterator(object):
"""Classe de manipulation de liste qui a essayé la chaîne de méthodes et l'exécution paresseuse comme LINQ
[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)
Si rien n'est fait, le contenu ne sera pas lié à Maya, je vais donc essayer de l'utiliser dans Maya.
iterator_v2.py
class EnumerableSelection(EnumerableIterator):
"""Itérateur de sélection d'objets
[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))
Il existe également des itertools et d'autres itertools, mais je préfère LINQ comme style d'écriture. Je pense que si je peux comprendre et utiliser davantage les spécifications du langage, je serai capable d'écrire dans un style pythonique. Je souhaite continuer à étudier en attendant des conseils et des conseils issus de domaines variés.
Recommended Posts