Comment savez-vous lorsque vous regardez la liste des attributs et méthodes répertoriés dans un DIR qui sont des attributs et quelles sont les méthodes?

StackOverflow https://stackoverflow.com/questions/880160

Question

Je travaille en essayant d'apprendre à programmer dans Python et je me concentre sur la meilleure gestion des modules standard et autres modules. La fonction DIR semble vraiment puissante dans l'interprète, mais je me demande si je manque quelque chose à cause de mon manque de fond. En utilisant le livre S.Lotts, j'ai décidé d'utiliser sa classe Die pour en savoir plus sur la syntaxe et l'utilisation des cours et des instances.

Voici le code d'origine:

class Die(object):
''' simulate a six-sided die '''
def roll(self):
    self.value=random.randrange(1,7)
    return self.value
def getValue(self):
    return self.value

Je regardais cela et après avoir créé quelques instances, je me demandais si la valeur du mot était un mot-clé en quelque sorte et quelle a fait l'utilisation de l'objet Word dans l'instruction de classe et j'ai donc décidé de le découvrir en modifiant la définition de la classe à ce qui suit:

class Die():
''' simulate a six-sided die '''
def roll(self):
    self.ban=random.randrange(1,7)
    return self.ban
def getValue(self):
    return self.ban

Ce changement m'a montré que j'ai obtenu le même comportement à partir de mes instances, mais les méthodes / attributs suivants manquaient dans les cas où j'ai fait DIR:

'__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__',
 '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__',
_repr__', '__setattr__', '__str__', '__weakref__'

J'ai également compris que lorsque j'ai fait un DIR sur une instance, j'avais un mot-clé supplémentaire-interdire Ce que j'ai finalement compris était un attribut de mon instance. Cela m'a aidé à comprendre que je pourrais utiliser d1.ban Pour accéder à la valeur de mon instance. La seule raison pour laquelle je pouvais comprendre que c'était un attribut était que je tape d1.Ally Et j'ai un AttributError J'ai compris que d1.getvalue était une méthode attachée pour mourir parce que c'est ce que l'interprète m'a dit.

Donc, quand j'essaie d'utiliser un module compliqué mais utile comme magnifique dir (instance). J'aurais besoin de le savoir parce que cela m'entre a appris qu'avec des attributs, j'appelle le résultat d'une méthode et avec des méthodes, j'invoque une fonction sur mon instance.

Cette question est probablement trop verbeuse, mais elle m'a certainement aidé à mieux comprendre la différence entre les attributs et les méthodes. Plus précisément, quand je regarde le résultat de l'appel DIR sur une instance de ma classe Die, je vois cela

['__doc__', '__module__', 'ban', 'getValue', 'roll']

Il semblerait donc utile de savoir en examinant cette liste qui sont des attributs et qui sont des méthodes sans avoir à recourir à des essais et à des erreurs ou à entraîner la saisie Hasattr (Myinstance, suspecteAttributeName).

Après avoir posté la question que j'ai essayée

for each in dir(d1):
    print hasattr(d1,each)

Ce qui me dit à proprement parler que toutes les méthodes sont des attributs. Mais je ne peux pas appeler une méthode sans le () Il me semble donc que le Hasattr () est trompeur.

Était-ce utile?

La solution

À la place de: "print hasattr(d1,each)", essayer: "print each, type(getattr(d1,each))". Vous devriez trouver les résultats informatifs.

Aussi, à la place de dir() essayer help(), ce que je pense que vous recherchez vraiment.

Autres conseils

Envisagez d'utiliser la bibliothèque standard inspect Module - C'est souvent l'approche la plus pratique de l'introspection, emballant des morceaux de fonctionnalité substantiels (vous pouvez implémenter cela à partir de zéro, mais réutiliser le code bien testé et bien conçu est une bonne chose). Voir http://docs.python.org/library/inspect.html pour tous les détails, mais par exemple inspect.getmembers(foo, inspect.ismethod) est un excellent moyen d'obtenir toutes les méthodes de FOO (vous obtiendrez (name, value) paires triées par nom).

Ce qui me dit à proprement parler que toutes les méthodes sont des attributs. Mais je ne peux pas appeler une méthode sans le () donc il me semble que le Hasattr () est trompeur.

Pourquoi est-il trompeur? Si obj.ban() est une méthode, alors obj.ban est l'attribut correspondant. Vous pouvez avoir du code comme ceci:

print obj.getValue()

ou

get = obj.getValue
print get()

Si vous souhaitez obtenir une liste de méthodes sur un objet, vous pouvez essayer cette fonction. Ce n'est pas parfait, car il se déclenchera également pour les attributs appelables qui ne sont pas des méthodes, mais pour 99% des cas devraient être assez bons:

def methods(obj):
    attrs = (getattr(obj, n) for n in dir(obj))
    return [a for a in attrs if a.hasattr("__call__")]

Cette info Le module inspiré de Dive dans Python sert le but.

def info(obj, spacing=20, collapse=1, variables=False):
    '''Print methods and their doc Strings

    Takes any object'''
    if variables:
    methodList = [method for method in dir(obj)]
    else:
    methodList = [method for method in dir(obj) if callable(getattr(obj,method))]

    #print methodList


    print '\n'.join(['%s %s' %
            (method.ljust(spacing),
             " ".join(str(getattr(obj,method).__doc__).split()))
            for method in methodList])


if __name__=='__main__':
    info(list)

Il existe une méthode intégrée appelée callable. Vous pouvez l'appliquer à n'importe quel objet et il renverra True / Faux selon qu'il peut être appelé. par exemple

>>> def foo():
...   print "This is the only function now"
...
>>> localDictionary = dir()
>>> for item in localDictionary:
...   print repr(item) + "is callable: " + str(callable(locals()[item]))
'__builtins__'is callable: False
'__doc__'is callable: False
'__name__'is callable: False
'foo'is callable: True

Remarque L'appel local () renvoie un dictionnaire contenant tout défini dans votre portée actuelle. Je l'ai fait parce que les éléments hors du dictionnaire ne sont que des chaînes, et nous devons exécuter appelable sur l'objet réel.

Idéalement, lorsque vous utilisez une bibliothèque compliquée comme BeautifulSoup, vous devez consulter sa documentation pour voir quelles méthodes fournit chaque classe. Cependant, dans le cas rare où vous n'avez pas de documentation facilement accessible, vous pouvez vérifier la présence de méthodes en utilisant les éléments suivants.

Toutes les méthodes, qui sont elles-mêmes des objets, implémentent le __call__ Méthode et peut être vérifié à l'aide de la méthode callable () qui renvoie True, si la valeur vérifiée a le __call__ méthode.

Le code suivant devrait fonctionner.

x = Die()
x.roll()

for attribute in dir(x) :
    print attribute, callable(getattr(x, attribute))

Le code ci-dessus retournerait vrai pour toutes les méthodes et faux pour tous les attributs non appelés (tels que les membres de données comme Ban). Cependant, cette méthode revient également True pour tous les objets appelés (comme les classes intérieures). Vous pouvez également vérifier si le type d'attribut est instancemethod

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