J'ai 2 solutions à un problème de récursivité dont j'ai besoin pour une fonction (en réalité une méthode). Je veux que ce soit récursif, mais je souhaite définir la limite de récursion à 10 et la réinitialiser une fois que la fonction est appelée (ou non en désordre avec la limite de récursivité). Quelqu'un peut-il penser à une meilleure façon de le faire ou de recommander en utilisant un sur les autres? Je suis penché vers le gestionnaire de contexte car il conserve mon Code Nettoyant et pas de réglage de la tracebacklimit, mais il pourrait y avoir des mises en garde? Je vois un comportement impair cependant avec le gestionnaire de contexte. Si je mettais dans la principale p> IT imprime 1 à 10. Si je fais de même de l'interprète, il imprime 1 à 11. Je suppose qu'il y a quelque chose qui se passe sous la hotte Quand j'importe des choses? p> Edit: Pour la postérité, voici ce que j'ai proposé pour une fonction qui connaît sa profondeur d'appel. Je doute que je l'utiliserais dans n'importe quel code de production, mais cela fait le travail. P> import sys
import inspect
class KeepTrack(object):
def __init__(self):
self.calldepth = sys.maxint
def func(self):
zero = len(inspect.stack())
if zero < self.calldepth:
self.calldepth = zero
i = len(inspect.stack())
print i - self.calldepth
if i - self.calldepth < 9:
self.func()
keeping_track = KeepTrack()
keeping_track.func()
4 Réponses :
J'aurais définitivement choisir la première approche, c'est plus simple et vous expliquant. Après que toute la limite de récursion est votre choix explicite, alors pourquoi l'obscurcir? P>
Vous ne devriez pas changer la limite de récursion du système. Vous devez coder votre fonction pour savoir à quel point c'est profondément, et mettre fin à la récursion quand il devient trop profond. P>
La raison pour laquelle la limite de récursion semble appliquée différemment dans votre programme et que l'interprète est dû au fait qu'ils ont des sommets différents de pile: les fonctions invoquées dans l'interprète pour atteindre le point d'exécuter votre code. p>
tandis que quelque peu tangentielle (je l'aurais mis dans un commentaire, mais je ne pense pas qu'il y ait de la place), il convient de noter que SETRecursionLimit est quelque peu nommé inhabituel - il définit en fait la profondeur maximale de la pile: P>
http://docs.python.org/library/sys.html# SyS.SetRecursionLimit P>
C'est pourquoi la fonction se comporte différemment en fonction de l'endroit où vous l'appelez. En outre, si Func2 devait apporter un appel STDLIB (ou autre chose) qui a fini par appeler un certain nombre de fonctions telles qu'il a ajouté plus que n à la pile, l'exception déclencherait tôt. P>
aussi aussi, je ne changerais pas non plus le système Sys.TraceBackLimit; Cela aura un effet sur le reste de votre programme. Aller avec la réponse de Ned. P>
Ignorer les problèmes les plus généraux, on dirait que vous pouvez obtenir la profondeur de cadre actuelle en regardant la longueur d'inspecteur.getTerFrames (). Cela vous donnerait un "point zéro" à partir desquels vous pouvez définir la limite de profondeur (non-responsabilité: je n'ai pas essayé cela). P>
EDIT: ou LEN (inspectez.stack ()) - Ce n'est pas clair pour moi quelle est la différence. Je serais intéressé à savoir si cela fonctionne et si elles étaient différentes. P>
Pourquoi ne pas simplement utiliser
pour _ en xrange (n) code> faire quelque chose n fois? Est conceptuellement plus simple que d'abuser d'unruntimeError code>, permet d'appeler d'autres fonctions sans quitter prématurément (ou, pire, nécessitant l'appelant de s'en occuper) et devrait être plus efficace en tant que bonus.Lorsque vous le faites dans Main, vous êtes déjà en fonction. Lorsque vous êtes dans l'interprète, vous n'êtes pas.
Pourquoi voudriez-vous éventuellement faire cela?
Vous pouvez utiliser des décorateurs pour vérifier la limite de récursion
Pouvez-vous éviter l'état mondial avec des décorateurs (et conserver la liste des appels de fonctions emballés propres)?
J'essaie d'attraper un Json à partir d'un serveur. Je ne sais pas combien de temps la réponse sera à l'avant, mais je veux faire appel à l'appel au plus i> dix fois. Récursion semble être la voie à suivre. ValueError est bien sûr incorrect. Juste un réflexe.