Question

Je voudrais contrôler les méthodes apparaissent lorsqu'un utilisateur utilise l'onglet d'achèvement sur un objet personnalisé dans ipython - en particulier, je veux cacher les fonctions que je déconseillés. Je veux encore que ces méthodes soient appelable, mais je ne veux pas que les utilisateurs de les voir et commencer à les utiliser si elles inspectent l'objet. Est-ce quelque chose qui est possible?

Était-ce utile?

La solution

réponse partielle pour vous. Je vais poster le code exemple et expliquer pourquoi sa seule une réponse partielle.
Code:

class hidden(object): # or whatever its parent class is
    def __init__(self):
        self.value = 4
    def show(self):
        return self.value
    def change(self,n):
        self.value = n
    def __getattr__(self, attrname):
        # put the dep'd method/attribute names here
        deprecateds = ['dep_show','dep_change']
        if attrname in deprecateds:
            print("These aren't the methods you're looking for.")
            def dep_change(n):
                self.value = n
            def dep_show():
                return self.value
            return eval(attrname)
        else:
            raise AttributeError, attrname

Alors maintenant, la mise en garde: ils ne sont pas des méthodes (noter l'absence de soi comme la première variable). Si vous avez besoin de vos utilisateurs (ou votre code) pour pouvoir appeler im_class, im_func ou im_self sur vos méthodes dépréciées, alors ce hack ne fonctionne pas. De plus, je suis sûr qu'il va être un coup de performance parce que vous définissez chaque fonction dep'd à l'intérieur __getattr__. Cela n'affectera pas vos autres attributs lookups (Si je les avais mis en __getattribute__, ce serait une autre affaire), mais il va ralentir l'accès à ces méthodes dépréciées. Cela peut être (en grande partie, mais pas tout à fait) niée en mettant chaque définition de fonction à l'intérieur de son propre si le bloc, au lieu de faire une vérification de liste de membres, mais, en fonction de la taille de votre fonction est, cela pourrait être très ennuyeux pour maintenir.

Mise à jour:

1) Si vous voulez faire les méthodes de fonctions dépréciées (et vous), il suffit d'utiliser

import types
return types.MethodType(eval(attrname), self)

au lieu de

return eval(attrname)

dans l'extrait ci-dessus, et ajoutez l'auto comme premier argument à la fonction defs. Il les transforme en instancemethods (vous pouvez utiliser im_class, im_func et im_self au contenu de votre coeur).

2) Si le crochet __getattr__ ne vous a pas de sensations fortes, il y a une autre option (que je connais) (albiet, avec ses propres mises en garde, et nous allons arriver à ceux-ci): Mettre les fonctions dépréciées définitions à l'intérieur __init__, et les cacher avec un __dir__ personnalisé. Voici à quoi ressemblera le code ci-dessus fait ainsi:

class hidden(object):
    def __init__(self):
        self.value = 4
        from types import MethodType
        def dep_show(self):
            return self.value
        self.__setattr__('dep_show', MethodType(dep_show, self))
        def dep_change(self, n):
            self.value = n
        self.__setattr__('dep_change', MethodType(dep_change, self))
    def show(self):
        return self.value
    def change(self, n):
        self.value = n
    def __dir__(self):
        heritage = dir(super(self.__class__, self)) # inherited attributes
        hide = ['dep_show', 'dep_change']
        show = [k for k in self.__class__.__dict__.keys() + self.__dict__.keys() if not k in heritage + private]
        return sorted(heritage + show)

L'avantage ici est que vous n'êtes pas définir les fonctions de nouveau chaque recherche, qui vous filets vitesse. L'inconvénient est ici parce que vous n'êtes pas définir des fonctions à nouveau chaque recherche, ils doivent « persistent » (si vous voulez). Ainsi, alors que la méthode __dir__ personnalisée cache vos deprecateds de dir(hiddenObj) et, par conséquent, onglet achèvement de IPython, ils existent encore dans l'attribut __dict__ de l'instance, où les utilisateurs peuvent les découvrir.

Autres conseils

Le DeprecationWarning n'est pas émis jusqu'à ce que la méthode est appelée, de sorte que vous devriez avoir un attribut distinct sur la classe qui stocke les noms des méthodes dépréciées, puis vérifier que, avant de suggérer une fin.

Vous pouvez marcher AST pour la méthode à la recherche de DeprecationWarning, mais échouera si une classe est définie en C, ou si la méthode peut émettre un DeprecationWarning en fonction du type ou la valeur des arguments.

À propos du mécanisme d'achèvement IPython, il est documenté ici:

http: // ipython .scipy.org / doc / manuel / html / api / produit / IPython.core.completer.html # ipcompleter

Mais un exemple vraiment intéressant pour vous est les traits completer, qui fait exactement ce que vous voulez faire. Il cache certaines méthodes (en fonction de leurs noms) de la saisie semi-automatique

Voici le code:

http: //projects.scipy .org / ipython / ipython / navigateur / ipython / trunk / IPython / extensions / ipy_traits_completer.py

On dirait que il y a un spécial méthode magique pour la introcpection qui est appelé par dir (): __dir__(). Est-ce pas ce que vous Lookin pour?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top