Qu'est-ce qu'un cas d'utilisation d'exemple pour une méthode de classe Python?

j'ai lu à quoi servent les méthodes de classe en Python? , mais les exemples dans ce post sont complexes. Je suis à la recherche d'une manière claire, simple, dépouillée exemple d'un cas d'utilisation particulier pour classmethods en Python.

pouvez-vous nommer un petit cas d'utilisation d'exemple spécifique où une méthode de classe Python serait le bon outil pour le travail?

56
demandé sur Community 2011-04-21 05:19:17

6 réponses

méthodes d'assistance pour l'initialisation:

class MyStream(object):

    @classmethod
    def from_file(cls, filepath, ignore_comments=False):    
        with open(filepath, 'r') as fileobj:
            for obj in cls(fileobj, ignore_comments):
                yield obj

    @classmethod
    def from_socket(cls, socket, ignore_comments=False):
        raise NotImplemented # Placeholder until implemented

    def __init__(self, iterable, ignore_comments=False):
       ...
45
répondu anijhaw 2015-05-23 18:42:11

bien __new__ est une méthode de classe assez importante. C'est là où les instances viennent habituellement de

donc dict() appels dict.__new__ bien sûr, mais il y a un autre moyen pratique de faire des dicts parfois qui est le classmethod dict.fromkeys()

par exemple.

>>> dict.fromkeys("12345")
{'1': None, '3': None, '2': None, '5': None, '4': None}
28
répondu John La Rooy 2011-04-21 02:01:41

Je ne sais pas, quelque chose comme les méthodes de constructeur nommées?

class UniqueIdentifier(object):

    value = 0

    def __init__(self, name):
        self.name = name

    @classmethod
    def produce(cls):
        instance = cls(cls.value)
        cls.value += 1
        return instance

class FunkyUniqueIdentifier(UniqueIdentifier):

    @classmethod
    def produce(cls):
        instance = super(FunkyUniqueIdentifier, cls).produce()
        instance.name = "Funky %s" % instance.name
        return instance

Utilisation:

>>> x = UniqueIdentifier.produce()
>>> y = FunkyUniqueIdentifier.produce()
>>> x.name
0
>>> y.name
Funky 1
18
répondu julkiewicz 2011-04-21 01:41:16

je trouve que j'utilise le plus souvent @classmethod pour associer un morceau de code à une classe, pour éviter de créer une fonction globale, pour les cas où je n'ai pas besoin d'une instance de la classe pour utiliser le code.

par exemple, je pourrais avoir une structure de données qui considère une clé valide seulement si elle est conforme à un certain modèle. Je souhaiterez peut-être utiliser ce de l'intérieur et à l'extérieur de la classe. Cependant, je ne veux pas créer encore une autre fonction globale:

def foo_key_is_valid(key):
    # code for determining validity here
    return valid

je préférerais regrouper CE code avec la classe à laquelle il est associé:

class Foo(object):

    @classmethod
    def is_valid(cls, key):
        # code for determining validity here
        return valid

    def add_key(self, key, val):
        if not Foo.is_valid(key):
            raise ValueError()
        ..

# lets me reuse that method without an instance, and signals that
# the code is closely-associated with the Foo class
Foo.is_valid('my key')
11
répondu samplebias 2011-04-21 01:39:18

la raison la plus importante pour utiliser un @classmethod est dans un constructeur alternatif qui est destiné à être hérité. Cela peut être très utile dans le polymorphisme. Un exemple:

class Shape(object):
    # this is an abstract class that is primarily used for inheritance defaults
    # here is where you would define classmethods that can be overridden by inherited classes
    @classmethod
    def from_square(cls, square):
        # return a default instance of cls
        return cls()

notez que Shape est une classe abstraite qui définit une méthode de classe from_square , puisque Shape n'est pas vraiment défini, il ne sait pas vraiment comment dériver d'une Square donc il retourne simplement une instance par défaut de la classe.

les classes héritées sont alors autorisées à définir leurs propres versions de cette méthode:

class Square(Shape):
    def __init__(self, side=10):
        self.side = side

    @classmethod
    def from_square(cls, square):
        return cls(side=square.side)


class Rectangle(Shape):
    def __init__(self, length=10, width=10):
        self.length = length
        self.width = width

    @classmethod
    def from_square(cls, square):
        return cls(length=square.side, width=square.side)


class RightTriangle(Shape):
    def __init(self, a=10, b=10):
        self.a = a
        self.b = b
        self.c = ((a*a) + (b*b))**(.5)

    @classmethod
    def from_square(cls, square):
        return cls(a=square.length, b=square.width)


class Circle(Shape):
    def __init__(self, radius=10):
        self.radius = radius

    @classmethod
    def from_square(cls, square):
        return cls(radius=square.length/2)

l'usage vous permet de traiter toutes ces classes non fondées polymorphiquement

square = Square(3)
for polymorphic_class in (Square, Rectangle, RightTriangle, Circle):
    this_shape = polymorphic_class.from_square(square)

tout cela est très bien et épatant, pourriez-vous dire, mais pourquoi ne pourrais-je pas utiliser comme @staticmethod pour accomplir ce même comportement polymorphe:

class Circle(Shape):
    def __init__(self, radius=10):
        self.radius = radius

    @staticmethod
    def from_square(square):
        return Circle(radius=square.length/2)

La réponse est que vous pouvez, mais vous n'obtenez pas l' avantages de l'héritage parce que Circle doit être appelé explicitement dans la méthode. Ce qui veut dire que si je l'appelle d'une classe héritée sans passer, j'obtiendrais toujours Circle à chaque fois.

notez ce qui est gagné quand je définit une autre classe de forme qui n'a pas vraiment de logique de_square personnalisée:

class Hexagon(Shape):
    def __init__(self, side=10):
        self.side = side

    # note the absence of classmethod here, this will use from_square it inherits from shape

ici, vous pouvez laisser le @classmethod indéfini et il utilisera la logique de Shape.from_square tandis que retenir cls de l'OMS et retourner la forme appropriée.

square = Square(3)
for polymorphic_class in (Square, Rectangle, RightTriangle, Circle, Hexagon):
    this_shape = polymorphic_class.from_square(square)
7
répondu krayzk 2017-07-17 19:53:34
in class MyClass(object):
    '''
    classdocs
    '''
    obj=0
    x=classmethod
    def __init__(self):
        '''
        Constructor
        '''
        self.nom='lamaizi'
        self.prenom='anas'
        self.age=21
        self.ville='Casablanca'
if __name__:
    ob=MyClass()
    print(ob.nom)
    print(ob.prenom)
    print(ob.age)
    print(ob.ville)
-3
répondu anas lamaizi 2015-02-09 20:17:49