[PYTHON] Apprenez avec FizzBuzz Iterator, Generator, Decorator

introduction

J'ai lu la documentation de python et j'ai découvert Iterator, Generator, Decorator, etc.

Qu'est-ce qu'Iterator (devis)

http://docs.python.jp/2/tutorial/classes.html#iterator (Commencez à citer) Ces méthodes d'accès sont claires, concises et pratiques. L'utilisation d'itérateurs est répandue dans Python et apporte l'unité. Dans les coulisses, l'instruction for appelle l'objet conteneur ʻiter (). Cette fonction renvoie un objet itérateur avec la méthode next ()définie. La méthodenext ()accède aux éléments du conteneur un par un. Lorsqu'il n'y a plus d'éléments auxquels accéder dans le conteneur,next ()lève une exceptionStopIterationet met fin à la boucle for. L'exemple suivant montre comment cela fonctionne réellement. (Omis) Une fois que vous avez vu le mécanisme derrière le protocole itérateur, il est facile d'ajouter un comportement itératif à votre classe. Assurez-vous de définir la méthodeiter ()pour renvoyer un objet avec la méthodenext ()`. Si la classe elle-même définit «next ()», «iter ()» peut simplement renvoyer «self». (Fin de la citation)

Si vous voulez vous faciliter la tâche, vous pouvez définir une classe avec la méthode __iter__ () et la méthode next (), et lancer une exception de StopIteration lorsque la condition de terminaison est satisfaite. Il semble que l'instance d'Iterator puisse être utilisée telle quelle dans l'instruction for.

code

J'ai écrit un FizzBuzzIterator avec des spécifications similaires en faisant référence à la fonction range ().

def fizzbuzz(n):
  n = int(n)
  if (n%15) == 0: return "FizzBuzz"
  elif (n%5) == 0: return "Buzz"
  elif (n%3) == 0: return "Fizz"
  else: return n

class FizzBuzzIterator:
  def __init__(self,start, stop, step=1):
    self.count = start
    self.stop = stop
    self.step = step

  def __iter__(self):
    return self

  def next(self):
    if (self.step > 0 and self.count >= self.stop) or (self.step < 0 and self.count <= self.stop):
      raise StopIteration
    else:
      result = fizzbuzz(self.count)
      self.count += self.step
      return result

Sortie FizzBuzz de 1 à 100

fbiter1 =  FizzBuzzIterator(1,101)
for fzbz in fbiter1: print fzbz

Sortie FizzBuzz uniquement pour les nombres impairs de 1 à 99

fbiter2 =  FizzBuzzIterator(1,101,2)
for fzbz in fbiter2: print fzbz

Sortie FizzBuzz dans l'ordre inverse de 100 à 1

fbiter3 =  FizzBuzzIterator(100,0,-1)
for fzbz in fbiter3: print fzbz

Qu'est-ce que Generator (devis)

http://docs.python.jp/2/tutorial/classes.html#generator (Commencez à citer) Le générateur est un outil concis et puissant pour créer des itérateurs. Le générateur est écrit comme une fonction normale, mais lorsqu'il renvoie des données, il utilise une instruction yield. Chaque fois que next () est appelé, le générateur reprend le traitement précédemment interrompu (le générateur se souvient de toutes les valeurs de données et de la dernière instruction exécutée). Si vous regardez l'exemple ci-dessous, vous pouvez voir que le générateur est très facile à créer. (Fin de la citation)

code

Iterator semblait travailler très dur, mais le générateur devrait-il être simplement un document pour? Cela m'a fait me demander.

def fizzbuzz(n):
  n = int(n)
  if (n%15) == 0: return "FizzBuzz"
  elif (n%5) == 0: return "Buzz"
  elif (n%3) == 0: return "Fizz"
  else: return n

def fizzbuzz_generator(start,finish,diff=1):
   for n in range(start,finish,diff):
     yield fizzbuzz(n)

for fzbz in fizzbuzz_generator(1,100):
  print fzbz

Qu'est-ce que le décorateur (devis)

http://docs.python.jp/2/glossary.html#term-decorator (Commencez à citer) (Décorateur) Une fonction qui renvoie une fonction. Il est généralement utilisé pour convertir une fonction avec la syntaxe «@ wrapper». Les utilisations courantes des décorateurs sont classmethod () et staticmethod ().

La grammaire du décorateur est le sucre de syntaxe. Les deux définitions de fonction suivantes sont sémantiquement identiques.

def f(...):
    ...
f = staticmethod(f)

@staticmethod
def f(...):
    ...

(Fin de la citation)

code

Je n'ai pas compris alors je l'ai écrit.

def fizzbuzz(n):
  n = int(n)
  if (n%15) == 0: return "FizzBuzz"
  elif (n%5) == 0: return "Buzz"
  elif (n%3) == 0: return "Fizz"
  else: return n

def fizzbuzz_decorator(func):
  def wrapper(*args, **kwargs):
    func(fizzbuzz(*args))
  return wrapper

@fizzbuzz_decorator
def f(n):
  print n

f(1)
f(2)
f(3)
f(4)
f(5)

Dans ce qui précède, il semble que f soit réécrit par l'expression de décorateur @ fizzbuzz_decorator, et f soit réécrit en fizzbuzz_decorator (f), c'est-à-dire la fonction wrapper () suivante.

def wrapper(*args, **kwargs):
  f(fizzbuzz(args[0]))

Par conséquent, il semble que la chaîne de caractères fizzbuzz soit sortie car l'argument de f est traité par la fonction fizzbuzz () puis passé au f d'origine.

Résultat d'exécution

1
2
Fizz
3
Buzz

Imbrication d'expression décoratrice (citation)

Il semble que les expressions de décorateur puissent également être imbriquées. http://docs.python.jp/2/reference/compound_stmts.html#function (Commencez à citer) Les définitions de fonction peuvent être enveloppées dans une ou plusieurs expressions de décorateur. Lorsque vous définissez une fonction, l'expression de décorateur est évaluée dans la portée qui contient la définition de fonction. Le résultat doit être un objet appelable qui prend un objet fonction comme seul argument. Au lieu d'un objet fonction, la valeur renvoyée est liée au nom de la fonction. Plusieurs décorateurs sont imbriqués et appliqués. (Fin de la citation)

def fizzbuzz(n):
  n = int(n)
  if (n%15) == 0: return "FizzBuzz"
  elif (n%5) == 0: return "Buzz"
  elif (n%3) == 0: return "Fizz"
  else: return n

def fizzbuzz_decorator(func):
  def wrapper(*args, **kwargs):
    func(fizzbuzz(*args))
  return wrapper

def fizzbuzz_decorator2(func):
  def wrapper(*args, **kwargs):
    for n in range(1,args[0]):
      func(n)
  return wrapper

@fizzbuzz_decorator2
@fizzbuzz_decorator
def f(n):
  print n

f(101)

C'est un modèle équivalent au suivant.

f = fizzbuzz_decorator2(fizzbuzz_decorator(f))

Résultat d'exécution

1
2
Fizz
3
Buzz
(Omis)
98
Fizz
Buzz

Il semble que vous puissiez passer des arguments au décorateur, donc je l'ajouterai à l'avenir dès que j'enquêterai.

Recommended Posts

Apprenez avec FizzBuzz Iterator, Generator, Decorator
Calculer la séquence de Fibonacci avec générateur et itérateur
FizzBuzz en Python3
Apprenez Python avec ChemTHEATER
Apprenez Zundokokiyoshi en utilisant LSTM
Pandas apprenant avec la chimioinfomatique
Apprentissage Scikit-Learn avec la chimioinfomatique
Apprenez avec Chemo Informatics Matplotlib
Apprenez avec Chemo Informatics NumPy
DCGAN avec TF Learn
Décorer avec un décorateur
Apprenez Pendulum-v0 avec DDPG
Fizzbuzz avec gestion des exceptions
Apprenez librosa avec un tutoriel 1
Apprenez les orbites elliptiques avec Chainer
Apprenez de nouvelles données avec PaintsChainer
Créez facilement un profil avec un décorateur