Ποιες είναι οι μέθοδοι τάξης στην Python για;

ψήφοι
216

Διδάσκω εγώ Python και πιο πρόσφατα το μάθημά μου ήταν ότι η Python δεν είναι η Java , και γι 'αυτό μόλις περάσει, ενώ γυρίζοντας όλες τις μεθόδους κατηγορίας μου σε λειτουργίες.

Τώρα συνειδητοποιώ ότι δεν χρειάζεται να χρησιμοποιούν μεθόδους Class για το τι θα γίνει με staticτις μεθόδους σε Java, αλλά τώρα δεν είμαι σίγουρος πότε θα τα χρησιμοποιήσει. Όλες οι συμβουλές που μπορώ να βρω για τις μεθόδους Python Class είναι προς την κατεύθυνση της αρχάριους όπως εγώ πρέπει να μείνουν μακριά από αυτά, και η τυπική τεκμηρίωση είναι πιο αδιαφανής όταν τα συζητάμε.

Υπάρχει κάποιος που έχει ένα καλό παράδειγμα χρησιμοποιώντας μια μέθοδο κατηγορίας σε Python ή τουλάχιστον μπορεί κάποιος να μου πει πότε μπορεί να χρησιμοποιηθεί λογικά μεθόδους Class;

Δημοσιεύθηκε 01/09/2008 στις 17:16
πηγή χρήστη
Σε άλλες γλώσσες...                            


16 απαντήσεις

ψήφοι
23

Εναλλακτικές κατασκευαστές είναι το κλασικό παράδειγμα.

Απαντήθηκε 01/09/2008 στις 17:27
πηγή χρήστη

ψήφοι
158

μέθοδοι Class είναι για το πότε θα πρέπει να έχετε μεθόδους που δεν είναι ειδικά για κάθε συγκεκριμένη περίπτωση, αλλά εξακολουθεί να περιλαμβάνει την τάξη με κάποιο τρόπο. Το πιο ενδιαφέρον πράγμα για αυτούς είναι ότι μπορεί να παρακαμφθεί από υποκατηγορίες, κάτι που δεν είναι απλά δυνατόν στατικές μεθόδους της Java ή λειτουργίες της μονάδας επιπέδου της Python.

Αν έχετε μια τάξη MyClass, και μια λειτουργία μονάδας επιπέδου που λειτουργεί στο MyClass (εργοστάσιο, εξάρτηση στέλεχος ένεση, κλπ), το ένα κάνει classmethod. Στη συνέχεια, θα είναι διαθέσιμο σε υποκατηγορίες.

Απαντήθηκε 01/09/2008 στις 17:45
πηγή χρήστη

ψήφοι
4

Τίμια? Δεν έχω βρει μια χρήση για staticmethod ή classmethod. Έχω ακόμα να δω μια πράξη που δεν μπορεί να γίνει χρησιμοποιώντας ένα παγκόσμιο λειτουργία ή μια μέθοδο παράδειγμα.

Θα ήταν διαφορετικά αν πύθωνα που χρησιμοποιούνται ιδιωτικό και προστατεύεται μέλη περισσότερο σαν Java κάνει. Στην Java, χρειάζομαι μια στατική μέθοδο για να είναι σε θέση να έχουν πρόσβαση σε ιδιωτική μέλη μιας παράδειγμα να κάνουμε πράγματα. Στην Python, που είναι σπάνια απαραίτητη.

Συνήθως, βλέπω ανθρώπους που χρησιμοποιούν staticmethods και classmethods όταν το μόνο που πραγματικά χρειάζεται να κάνετε είναι επιπέδου λειτουργικής μονάδας χρήση python για ονομάτων καλύτερα.

Απαντήθηκε 01/09/2008 στις 17:54
πηγή χρήστη

ψήφοι
60

μεθόδους Factory (εναλλακτική κατασκευαστές) είναι πράγματι ένα κλασικό παράδειγμα των μεθόδων τάξη.

Βασικά, οι μέθοδοι της κατηγορίας είναι κατάλληλες κάθε φορά που θα ήθελαν να έχουν μια μέθοδο που ταιριάζει φυσικά στο χώρο ονομάτων της κατηγορίας, αλλά δεν συνδέεται με ένα συγκεκριμένο στιγμιότυπο της κλάσης.

Ως παράδειγμα, στην άριστη Unipath μονάδα:

Τρέχουσα κατάλογο

  • Path.cwd()
    • Επιστρέψτε την πραγματική τρέχοντα κατάλογο? π.χ., Path("/tmp/my_temp_dir"). Αυτή είναι μια μέθοδος τάξη.
  • .chdir()
    • Κάντε τον εαυτό του τρέχοντα κατάλογο.

Καθώς ο τρέχων κατάλογος είναι διαδικασία ευρύ, η cwdμέθοδος δεν έχει καμία ιδιαίτερη περίπτωση με την οποία θα πρέπει να συνδέονται. Ωστόσο, η αλλαγή του cwdστον κατάλογο ενός συγκεκριμένου Pathπερίπτωση θα πρέπει πράγματι να είναι μια μέθοδος παράδειγμα.

Χμμμ ... και Path.cwd()όντως επιστρέψει ένα Pathπαράδειγμα, υποθέτω ότι θα μπορούσε να θεωρηθεί μια μέθοδος εργοστάσιο ...

Απαντήθηκε 01/09/2008 στις 18:08
πηγή χρήστη

ψήφοι
6

Δούλευα με PHP και πρόσφατα ρωτούσα τον εαυτό μου, τι συμβαίνει με αυτό το classmethod; Εγχειρίδιο Python είναι πολύ τεχνική και πολύ σύντομα στα λόγια γι 'αυτό δεν θα βοηθήσει με κατανόηση αυτό το χαρακτηριστικό. Ήμουν googling και googling και βρήκα την απάντηση -> http://code.anjanesh.net/2007/12/python-classmethods.html .

Αν είστε τεμπέλης για να το κλικ. Η εξήγησή μου είναι μικρότερη και πιο κάτω. :)

στην PHP (ίσως όχι όλοι σας γνωρίζετε PHP, αλλά αυτή η γλώσσα είναι τόσο απλό που ο καθένας πρέπει να καταλάβει τι μιλάω) έχουμε στατικές μεταβλητές όπως αυτό:


class A
{

    static protected $inner_var = null;

    static public function echoInnerVar()
    {
        echo self::$inner_var."\n";
    }

    static public function setInnerVar($v)
    {
        self::$inner_var = $v;
    }

}

class B extends A
{
}

A::setInnerVar(10);
B::setInnerVar(20);

A::echoInnerVar();
B::echoInnerVar();

Η έξοδος θα είναι και στις δύο περιπτώσεις 20.

Ωστόσο, σε python μπορούμε να προσθέσουμε @classmethod διακοσμητή και ως εκ τούτου δεν είναι δυνατόν να έχουμε έξοδο 10 και 20 αντίστοιχα. Παράδειγμα:


class A(object):
    inner_var = 0

    @classmethod
    def setInnerVar(cls, value):
        cls.inner_var = value

    @classmethod
    def echoInnerVar(cls):
        print cls.inner_var


class B(A):
    pass


A.setInnerVar(10)
B.setInnerVar(20)

A.echoInnerVar()
B.echoInnerVar()

Έξυπνο, δεν είναι;

Απαντήθηκε 22/02/2010 στις 12:27
πηγή χρήστη

ψήφοι
26

Ήθελα πρόσφατα μια τάξη υλοτομία πολύ ελαφρύ που θα ποικίλες εξόδου ποσότητες παραγωγής, ανάλογα με το επίπεδο καταγραφής που θα μπορούσε να οριστεί μέσω προγραμματισμού. Αλλά δεν ήθελα να υπόσταση στην τάξη κάθε φορά που ήθελα να εξάγει ένα μήνυμα εντοπισμού σφαλμάτων ή σφάλμα ή προειδοποίηση. Αλλά ήθελα επίσης να ενσωματώσει τη λειτουργία του εν λόγω μηχανισμού καταγραφής και να είναι επαναχρησιμοποιήσιμα χωρίς δήλωση σχετικά με οποιαδήποτε globals.

Γι 'αυτό και χρησιμοποιούνται μεταβλητές τάξη και την @classmethodδιακοσμητής για να επιτευχθεί αυτό.

Με απλή κλάση Καταγραφή μου, θα μπορούσα να κάνω τα εξής:

Logger._level = Logger.DEBUG

Στη συνέχεια, τον κωδικό μου, αν ήθελα να φτύσει μια δέσμη των πληροφοριών εντοπισμού σφαλμάτων, απλά έπρεπε να κωδικοποιήσει

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

Λάθη θα μπορούσαν να τις βάλει με

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

Στο περιβάλλον «παραγωγή», μπορώ να καθορίσετε

Logger._level = Logger.ERROR

και τώρα, μόνο το μήνυμα σφάλματος θα είναι έξοδος. Το μήνυμα εντοπισμού σφαλμάτων δεν θα εκτυπωθεί.

Εδώ είναι τάξη μου:

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

Και μερικοί κώδικα που ελέγχει απλά ένα κομμάτι:

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()
Απαντήθηκε 11/05/2010 στις 00:48
πηγή χρήστη

ψήφοι
4

μέθοδοι Class προσφέρει μια «σημασιολογική ζάχαρη» (δεν ξέρω αν αυτός ο όρος χρησιμοποιείται ευρέως) - ή «σημασιολογική ευκαιρίας».

Παράδειγμα: έχεις ένα σύνολο κατηγοριών που αντιπροσωπεύουν αντικείμενα. Μπορεί να θέλετε να έχετε τη μέθοδο τάξη all()ή find()να γράψει User.all()ή User.find(firstname='Guido'). Αυτό θα μπορούσε να γίνει με τη χρήση λειτουργιών επιπέδου ενότητας του μαθήματος ...

Απαντήθηκε 17/08/2010 στις 14:53
πηγή χρήστη

ψήφοι
44

Σκεφτείτε το αυτό τον τρόπο: συνήθεις μέθοδοι είναι χρήσιμες για να κρύψει τις λεπτομέρειες της αποστολής: μπορείτε να πληκτρολογήσετε myobj.foo()χωρίς να ανησυχείτε για το αν η foo()μέθοδος υλοποιείται από την myobjκλάση αντικειμένου ή μία από τις μητρικές τάξεις της. Μέθοδοι Class είναι ακριβώς ανάλογη με αυτό, αλλά με το αντικείμενο της κατηγορίας και όχι: θα σας αφήσει να καλούν MyClass.foo()χωρίς να χρειάζεται να ανησυχείτε για το αν foo()εφαρμόζεται ειδικά από MyClass, επειδή χρειάζεται τα δικά της εξειδικευμένα εκδοχή του, ή αν έχει αφήσει μητρική της κατηγορίας του να χειριστεί την κλήση.

Μέθοδοι Class είναι απαραίτητη όταν κάνετε set-up ή υπολογισμού που προηγείται της δημιουργίας ενός πραγματικού παράδειγμα, γιατί μέχρι να υπάρχει η περίπτωση προφανώς δεν μπορούν να χρησιμοποιήσουν το παράδειγμα ως το σημείο αποστολής για τη μέθοδο κλήσεις σας. Ένα καλό παράδειγμα μπορούν να προβληθούν στον πηγαίο κώδικα SQLAlchemy? ρίξτε μια ματιά στην dbapi()μέθοδο τάξη στο ακόλουθο link:

https://github.com/zzzeek/sqlalchemy/blob/ab6946769742602e40fb9ed9dde5f642885d1906/lib/sqlalchemy/dialects/mssql/pymssql.py#L47

Μπορείτε να δείτε ότι η dbapi()μέθοδος, η οποία χρησιμοποιεί ένα backend βάση δεδομένων για την εισαγωγή του πωλητή ειδικά βιβλιοθήκη βάσης δεδομένων που χρειάζεται για on-demand, είναι μια μέθοδος τάξη, διότι πρέπει να τρέξει πριν περιπτώσεις μια συγκεκριμένη σύνδεση βάσης δεδομένων αρχίσετε να πάρει δημιουργήθηκε - αλλά ότι δεν μπορεί να είναι μια απλή λειτουργία ή στατική λειτουργία, επειδή θέλουν να είναι σε θέση να καλέσει άλλους, υποστηρίζοντας τις μεθόδους που μπορεί να χρειαστεί ομοίως να γράψει πιο συγκεκριμένα στις υποκατηγορίες από το γονέα κατηγορία τους. Και αν αποστολή σε λειτουργία ή στατικό τάξη, τότε θα «ξεχάσει» και να χάσουν τη γνώση σχετικά με το ποια τάξη κάνει την αρχικοποιείται.

Απαντήθηκε 19/08/2010 στις 11:51
πηγή χρήστη

ψήφοι
10

Νομίζω ότι το πιο σαφή απάντηση είναι AmanKow είναι ένα. Βράζει κάτω στο πώς και θέλουν να οργανώσουν τον κωδικό σας. Μπορείτε να γράψετε τα πάντα και λειτουργίες επίπεδο λειτουργικής μονάδας που είναι τυλιγμένο στο χώρο ονομάτων της μονάδας, δηλαδή

module.py (file 1)
---------
def f1() : pass
def f2() : pass
def f3() : pass


usage.py (file 2)
--------
from module import *
f1()
f2()
f3()
def f4():pass 
def f5():pass

usage1.py (file 3)
-------------------
from usage import f4,f5
f4()
f5()

Η παραπάνω διαδικαστικός κώδικας δεν είναι καλά οργανωμένη, όπως μπορείτε να δείτε μετά από μόλις 3 ενότητες γίνεται σύγχυση, τι κάθε μέθοδος κάνει; Μπορείτε να χρησιμοποιήσετε μεγάλη περιγραφικά ονόματα για τις λειτουργίες (όπως σε java), αλλά ακόμα κωδικό σας παίρνει ανεξέλεγκτες πολύ γρήγορα.

Η αντικειμενοστραφής τρόπος είναι να σπάσει τον κωδικό σας σε εύχρηστες δομικές μονάδες, δηλαδή κλάσεις και τα αντικείμενα και τις λειτουργίες μπορεί να σχετίζονται με αντικείμενα περιπτώσεις ή κατηγορίες.

Με λειτουργίες κατηγορίας θα κερδίσουν ένα άλλο επίπεδο διαίρεσης στον κώδικά σας σε σχέση με τις λειτουργίες επίπεδο μονάδας. Έτσι, μπορείτε να ομαδοποιήσετε σχετικές λειτουργίες μέσα σε μια τάξη για να γίνουν πιο συγκεκριμένες σε μια εργασία που αποδίδεται σε αυτή την κατηγορία. Για παράδειγμα, μπορείτε να δημιουργήσετε μια τάξη βοηθητικό αρχείο:

class FileUtil ():
  def copy(source,dest):pass
  def move(source,dest):pass
  def copyDir(source,dest):pass
  def moveDir(source,dest):pass

//usage
FileUtil.copy("1.txt","2.txt")
FileUtil.moveDir("dir1","dir2")

Με αυτό τον τρόπο είναι πιο ευέλικτη και πιο διατηρήσιμη, θα λειτουργεί ομάδα μαζί και πιο φανερό της σε ό, τι κάνει κάθε λειτουργία. Επίσης να σας αποτρέψει όνομα συγκρούσεις, για παράδειγμα, μπορεί να υπάρχει το αντίγραφο λειτουργίας σε άλλο εισάγονται μονάδα (για αντιγραφή παράδειγμα δικτύου) που χρησιμοποιείτε στον κώδικά σας, έτσι ώστε όταν χρησιμοποιείτε το πλήρες όνομα FileUtil.copy () να αφαιρέσετε το πρόβλημα και τις δύο λειτουργίες αντιγραφής μπορεί να χρησιμοποιηθεί δίπλα-δίπλα.

Απαντήθηκε 14/05/2011 στις 09:24
πηγή χρήστη

ψήφοι
8

Όταν ένας χρήστης συνδέεται στο στην ιστοσελίδα μου, ένας χρήστης () αντικείμενο αρχικοποιείται από το όνομα χρήστη και τον κωδικό πρόσβασης.

Αν χρειάζομαι ένα αντικείμενο χρήστη χωρίς ο χρήστης να είναι εκεί για να συνδεθείτε (π.χ. ένας χρήστης διαχειριστής μπορεί να θέλετε να διαγράψετε το λογαριασμό άλλοι χρήστες, γι 'αυτό πρέπει να υπόσταση σε αυτό το χρήστη και να καλέσει διαγραφής μέθοδο):

Έχω μεθόδους τάξη για να αρπάξει το αντικείμενο χρήστη.

class User():
    #lots of code
    #...
    # more code

    @classmethod
    def get_by_username(cls, username):
        return cls.query(cls.username == username).get()

    @classmethod
    def get_by_auth_id(cls, auth_id):
        return cls.query(cls.auth_id == auth_id).get()
Απαντήθηκε 26/03/2012 στις 05:36
πηγή χρήστη

ψήφοι
2

Αυτό είναι ένα ενδιαφέρον θέμα. να μου σχετικά με αυτό είναι ότι python classmethod λειτουργεί σαν μονήρεις και όχι ένα εργοστάσιο (η οποία επιστρέφει μια παρήγαγε ένα παράδειγμα μιας κατηγορίας). Ο λόγος είναι μονήρεις είναι ότι υπάρχει ένα κοινό αντικείμενο που παράγεται (το λεξικό), αλλά μόνο μία φορά για την τάξη, αλλά μοιράζονται όλες τις περιπτώσεις.

Για να φανεί αυτό εδώ είναι ένα παράδειγμα. Σημειώστε ότι όλες οι περιπτώσεις έχουν σχέση με την ενιαία λεξικό. Αυτό δεν είναι πρότυπο εργοστάσιο όπως το αντιλαμβάνομαι. Αυτό είναι πιθανώς πολύ μοναδικό σε python.

class M():
 @classmethod
 def m(cls, arg):
     print "arg was",  getattr(cls, "arg" , None),
     cls.arg = arg
     print "arg is" , cls.arg

 M.m(1)   # prints arg was None arg is 1
 M.m(2)   # prints arg was 1 arg is 2
 m1 = M()
 m2 = M() 
 m1.m(3)  # prints arg was 2 arg is 3  
 m2.m(4)  # prints arg was 3 arg is 4 << this breaks the factory pattern theory.
 M.m(5)   # prints arg was 4 arg is 5
Απαντήθηκε 07/09/2012 στις 04:06
πηγή χρήστη

ψήφοι
6

Σας επιτρέπει να γράψετε γενικές μεθόδους τάξη που μπορείτε να χρησιμοποιήσετε με οποιαδήποτε συμβατή τάξη.

Για παράδειγμα:

@classmethod
def get_name(cls):
    print cls.name

class C:
    name = "tester"

C.get_name = get_name

#call it:
C.get_name()

Αν δεν χρησιμοποιείτε @classmethod, μπορείτε να το κάνετε με τον εαυτό λέξη-κλειδί, αλλά χρειάζεται ένα στιγμιότυπο της κλάσης:

def get_name(self):
    print self.name

class C:
    name = "tester"

C.get_name = get_name

#call it:
C().get_name() #<-note the its an instance of class C
Απαντήθηκε 26/12/2012 στις 13:11
πηγή χρήστη

ψήφοι
1

Ρωτούσα τον εαυτό μου την ίδια ερώτηση μερικές φορές. Και παρόλο που τα παιδιά εδώ προσπάθησαν σκληρά για να το εξηγήσω, IMHO η καλύτερη απάντηση (και πιο απλή) απάντηση που έχω βρει είναι η περιγραφή της μεθόδου κατηγορίας στην τεκμηρίωση Python.

Υπάρχει επίσης αναφορά στη στατική μέθοδο. Και σε περίπτωση που κάποιος γνωρίζει ήδη παράδειγμα μεθόδους (που υποθέτω), αυτή η απάντηση θα μπορούσε να είναι το τελευταίο κομμάτι για να το πούμε όλοι μαζί ...

Περαιτέρω και πιο βαθιά επεξεργασία για το θέμα αυτό μπορείτε να βρείτε επίσης στην τεκμηρίωση: Το πρότυπο ιεραρχίας τύπου (μετακινηθείτε προς τα κάτω για να μεθόδων Πρωτοδικείο τμήμα)

Απαντήθηκε 14/10/2014 στις 06:07
πηγή χρήστη

ψήφοι
0

Μια τάξη ορίζει ένα σύνολο περιπτώσεων, φυσικά. Και οι μέθοδοι ενός έργου τάξης στις μεμονωμένες περιπτώσεις. Οι μέθοδοι κλάσης (και μεταβλητών) ένα μέρος για να μείνετε άλλες πληροφορίες που σχετίζονται με το σύνολο των περιπτώσεων πάνω από όλα.

Για παράδειγμα, εάν τάξη σας καθορίζει μια το σύνολο των μαθητών μπορεί να θέλετε μεταβλητές ή τις μεθόδους που ορίζουν τα πράγματα όπως το σύνολο της τάξης οι μαθητές μπορούν να είναι μέλη της τάξης.

Μπορείτε επίσης να χρησιμοποιήσετε τις μεθόδους τάξη να καθορίσει τα εργαλεία για την εργασία σε ολόκληρο το σύνολο. Για παράδειγμα Student.all_of_em () μπορεί να επιστρέψει όλα τα γνωστά μαθητές. Προφανώς, εάν η συσκευή σας περιπτώσεις έχουν περισσότερη δομή από ένα σύνολο που μπορεί να προσφέρει μεθόδους τάξη να ξέρετε για αυτή τη δομή. Students.all_of_em (βαθμός = 'juniors')

Τεχνικές όπως αυτό τείνουν να οδηγούν σε αποθήκευση μέλη του συνόλου των περιπτώσεων στις δομές δεδομένων που έχουν τις ρίζες τους σε μεταβλητές τάξη. Θα πρέπει να φροντίσει να αποφύγει τη ματαίωση της συλλογής σκουπιδιών στη συνέχεια.

Απαντήθηκε 08/09/2016 στις 00:29
πηγή χρήστη

ψήφοι
2

Τι ακριβώς με χτύπησε, που προέρχονται από Ruby, είναι ότι το λεγόμενο τάξης μέθοδο και το λεγόμενο παράδειγμα η μέθοδος είναι απλά μια συνάρτηση με την σημασιολογική έννοια που εφαρμόζεται στην πρώτη παράμετρο, η οποία είναι σιωπηλά πέρασε, όταν η λειτουργία καλείται ως μέθοδος ένα αντικείμενο (δηλαδή obj.meth()).

Κανονικά ότι το αντικείμενο πρέπει να είναι ένα στιγμιότυπο, αλλά η @classmethod μέθοδος διακοσμητής αλλάζει τους κανόνες για να περάσει μια τάξη. Μπορείτε να καλέσετε μια μέθοδο κλάσης σε μια παρουσία (είναι απλώς μια λειτουργία) - η πρώτη argyment θα είναι της κατηγορίας του.

Επειδή είναι απλά μια λειτουργία , μπορεί να δηλωθεί μόνο μια φορά σε κάθε δεδομένη έκταση (π.χ. classορισμός). Αν εξής, ως εκ τούτου, ως έκπληξη για μια Rubyist, που δεν μπορείτε να έχετε μια μέθοδο τάξη και μια μέθοδο παράδειγμα με το ίδιο όνομα .

Σκεφτείτε το εξής:

class Foo():
  def foo(x):
    print(x)

Μπορείτε να καλέσετε fooσε περίπτωση

Foo().foo()
<__main__.Foo instance at 0x7f4dd3e3bc20>

Αλλά όχι σε μια τάξη:

Foo.foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method foo() must be called with Foo instance as first argument (got nothing instead)

Τώρα προσθέστε @classmethod:

class Foo():
  @classmethod
  def foo(x):
    print(x)

Καλώντας ένα παράδειγμα περνά τώρα κατηγορίας του:

Foo().foo()
__main__.Foo

όπως και η έκκληση για μια κατηγορία:

Foo.foo()
__main__.Foo

Είναι μόνο σύμβαση που υπαγορεύει ότι θα χρησιμοποιήσετε selfγια την εν λόγω πρώτο επιχείρημα σε μια μέθοδο παράδειγμα και clsσε μια μέθοδο τάξης. Θα χρησιμοποιηθεί ούτε εδώ για να δείξει ότι είναι απλά ένα επιχείρημα. Στην Ruby, selfείναι μια λέξη-κλειδί.

Αντίθεση με Ruby:

class Foo
  def foo()
    puts "instance method #{self}"
  end
  def self.foo()
    puts "class method #{self}"
  end
end

Foo.foo()
class method Foo

Foo.new.foo()
instance method #<Foo:0x000000020fe018>

Η μέθοδος κατηγορία Python είναι απλά ένα διακοσμημένο λειτουργία και μπορείτε να χρησιμοποιήσετε τις ίδιες τεχνικές για να δημιουργήσετε το δικό σας διακοσμητές . Μια διακοσμημένο μέθοδος τυλίγει την πραγματική μέθοδο (σε περίπτωση @classmethodπου περάσει το πρόσθετο επιχείρημα τάξη). Η βασική μέθοδος είναι ακόμα εκεί, κρυμμένο αλλά ακόμα προσβάσιμα .


υποσημείωση: Έγραψα αυτό μετά από μια σύγκρουση ονομάτων μεταξύ μια τάξη και χάριν μέθοδο κέντρισε την περιέργειά μου. Είμαι μακριά από έναν ειδικό Python και θα ήθελα τα σχόλια εάν κάποιο από αυτό είναι λάθος.

Απαντήθηκε 24/03/2017 στις 18:45
πηγή χρήστη

ψήφοι
0

@classmethodμπορεί να είναι χρήσιμη για την εύκολη εμφανίσεων αντικείμενα αυτής της κατηγορίας από εξωτερικές πηγές. Σκέψου τα ακόλουθα:

import settings

class SomeClass:
    @classmethod
    def from_settings(cls):
        return cls(settings=settings)

    def __init__(self, settings=None):
        if settings is not None:
            self.x = settings['x']
            self.y = settings['y']

Στη συνέχεια, σε ένα άλλο αρχείο:

from some_package import SomeClass

inst = SomeClass.from_settings()

Πρόσβαση inst.x θα δώσει την ίδια αξία με τις ρυθμίσεις [ «x»].

Απαντήθηκε 15/11/2019 στις 15:19
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more