284 votes

Quelles sont les méthodes de la Classe en Python?

J'apprends Python et ma dernière leçon à tirer est que Python n'est pas en Java, et donc j'ai juste passé un moment de tourner toutes mes méthodes de la Classe en fonctions.

Je me rends compte maintenant que je n'ai pas besoin d'utiliser les méthodes de la Classe pour ce que je fait avec static méthodes en Java, mais maintenant, je ne suis pas sûr quand je les utiliserais. Tous les conseils que je peux trouver sur Python les méthodes de la Classe est le long de la lignes de débutants comme moi devraient orienter clairement d'entre eux, et le standard de la documentation est à son plus opaque lors de la discussion.

Quelqu'un aurait-il un bon exemple d'utilisation d'une méthode de Classe en Python ou au moins quelqu'un peut me dire quand les méthodes de la Classe peut être avantageusement utilisé?

202voto

John Millikin Points 86775

Les méthodes de la classe sont pour quand vous avez besoin d'avoir des méthodes qui ne sont pas spécifiques à une instance particulière, mais encore par la classe d'une certaine façon. La chose la plus intéressante à leur sujet est qu'ils peuvent être remplacées par des sous-classes, quelque chose qui n'est tout simplement pas possible en Java de méthodes statiques ou Python module-fonctions de niveau.

Si vous avez une classe MyClass, et un module de fonction de niveau qui fonctionne sur MyClass (usine d'injection de dépendance stub, etc), assurez - classmethod. Ensuite, il sera disponible pour les sous-classes.

69voto

AmanKow Points 732

Usine de méthodes alternatives (constructeurs) sont en effet un exemple classique de méthodes de la classe.

Fondamentalement, les méthodes de classe sont adaptés à tout moment vous souhaitez avoir une méthode qui s'inscrit naturellement dans l'espace de noms de la classe, mais n'est pas associée à une instance particulière de la classe.

Comme un exemple, dans l'excellente unipath module:

Répertoire courant

  • Path.cwd()
    • Retour au réel répertoire courant; par exemple, Path("/tmp/my_temp_dir"). C'est une méthode de classe.
  • .chdir()
    • Faire soi-même est le répertoire courant.

Le répertoire courant est un processus de large, l' cwd méthode n'a pas d'exemple particulier avec qui il doit être associé. Toutefois, la modification de l' cwd pour le répertoire d'un Path exemple devrait en effet être une méthode d'instance.

Hmmm... comme Path.cwd() , en effet, de retour d'un Path exemple, je suppose que cela pourrait être considéré comme une méthode de fabrique...

52voto

Brandon Rhodes Points 21188

Pensez-y de cette façon: normal méthodes sont utiles pour masquer les détails de l'expédition: vous pouvez taper myobj.foo() sans se soucier de savoir si l' foo() méthode est mise en œuvre par l' myobj classe de l'objet ou de l'une de ses classes parentes. Les méthodes de la classe sont exactement analogue, mais avec la classe de l'objet à la place: ils vous permettent d'appeler MyClass.foo() sans avoir à vous soucier foo() est mis en œuvre spécialement en MyClass car elle a besoin de son propre version spécialisée, ou si c'est de laisser sa classe parente traiter l'appel.

Les méthodes de la classe sont essentielles lorsque vous faites du set-up ou de calcul qui précède la création d'une instance réelle, parce que jusqu'à ce que l'instance existe de toute évidence vous ne pouvez pas utiliser l'instance que l'envoi, pour vos appels de méthode. Un bon exemple peut être vu dans la SQLAlchemy code source; - de prendre un coup d'oeil à l' dbapi() méthode de la classe sur le lien suivant:

http://hg.sqlalchemy.org/sqlalchemy/file/230819db717a/lib/sqlalchemy/dialects/mssql/pymssql.py

Vous pouvez voir que l' dbapi() méthode, qui est une base de données backend utilise pour importer spécifique au fournisseur de base de données de la bibliothèque dont il a besoin à la demande, est une méthode de la classe parce qu'il a besoin de courir avant de les occurrences de la base de données de connexion de commencer à se créé - mais qu'il ne peut pas être une simple fonction ou une fonction statique, parce qu'ils veulent être en mesure d'appeler les autres, en soutenant les méthodes susceptibles de même besoin d'être écrit plus précisément dans les sous-classes que dans leur classe parent. Et si vous envoi à une fonction ou d'une classe statique, vous "oubliez" et de perdre la connaissance de la classe est en train de faire l'initialisation.

31voto

Marvo Points 5444

J'ai récemment voulu un très léger-poids classe de log qui serait sortie des quantités variables de sortie en fonction du niveau d'enregistrement peut être réglée par programme. Mais je ne voulais pas d'instancier la classe à chaque fois que je voulais à la sortie d'un message de débogage ou d'erreur ou d'avertissement. Mais je voulais aussi encapsuler le fonctionnement de cette fonction de journalisation et de le rendre réutilisable sans la déclaration de toutes les variables globales.

Alors j'ai utilisé des variables de classe et l' @classmethod décorateur pour atteindre cet objectif.

Avec ma classe de log, j'ai pu effectuer les opérations suivantes:

Logger._level = Logger.DEBUG

Alors, dans mon code, si je voulais cracher un tas d'informations de débogage, j'ai simplement eu à code

Logger.debug( "this is some annoying message I only want to see while debugging" )

Les erreurs pourraient être mis avec

Logger.error( "Wow, something really awful happened." )

Dans la "production" de l'environnement, je peux préciser

Logger._level = Logger.ERROR

et maintenant, seul le message d'erreur sera de sortie. Le message de débogage ne sera pas imprimé.

Voici ma classe:

class Logger :
    ''' Handles logging of debugging and error messages. '''

    DEBUG = 5
    INFO  = 4
    WARN  = 3
    ERROR = 2
    FATAL = 1
    _level = DEBUG

    def __init__( self ) :
        Logger._level = Logger.DEBUG

    @classmethod
    def isLevel( cls, level ) :
        return cls._level >= level

    @classmethod
    def debug( cls, message ) :
        if cls.isLevel( Logger.DEBUG ) :
            print "DEBUG:  " + message

    @classmethod
    def info( cls, message ) :
        if cls.isLevel( Logger.INFO ) :
            print "INFO :  " + message

    @classmethod
    def warn( cls, message ) :
        if cls.isLevel( Logger.WARN ) :
            print "WARN :  " + message

    @classmethod
    def error( cls, message ) :
        if cls.isLevel( Logger.ERROR ) :
            print "ERROR:  " + message

    @classmethod
    def fatal( cls, message ) :
        if cls.isLevel( Logger.FATAL ) :
            print "FATAL:  " + message

Et un peu de code qui teste juste un peu:

def logAll() :
    Logger.debug( "This is a Debug message." )
    Logger.info ( "This is a Info  message." )
    Logger.warn ( "This is a Warn  message." )
    Logger.error( "This is a Error message." )
    Logger.fatal( "This is a Fatal message." )

if __name__ == '__main__' :

    print "Should see all DEBUG and higher"
    Logger._level = Logger.DEBUG
    logAll()

    print "Should see all ERROR and higher"
    Logger._level = Logger.ERROR
    logAll()

29voto

Aaron Maenpaa Points 39173

Alternative constructeurs sont un exemple classique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X