una poo otra multiple metodos metodo llamar instanciar importar herencia funciones como clases clase python class class-method

poo - llamar metodo de otra clase python



¿Qué es un caso de uso de ejemplo para un método de clase Python? (6)

Bueno __new__ es un método de clase bastante importante. Es de donde generalmente provienen las instancias

así que dict() llama dict.__new__ por supuesto, pero hay otra forma práctica de hacer dicts a veces, que es el classmethod dict.fromkeys()

p.ej.

>>> dict.fromkeys("12345") {''1'': None, ''3'': None, ''2'': None, ''5'': None, ''4'': None}

He leído para qué son los métodos de clase en Python? pero los ejemplos en esa publicación son complejos. Estoy buscando un ejemplo claro, simple y escueto de un caso de uso particular para classmethods en Python.

¿Puedes nombrar un caso de uso de ejemplo pequeño y específico donde un método de clase de Python sería la herramienta adecuada para el trabajo?


Encuentro que con mayor frecuencia uso @classmethod para asociar un fragmento de código con una clase, para evitar la creación de una función global, para los casos en que no requiera una instancia de la clase para usar el código.

Por ejemplo, podría tener una estructura de datos que solo considere una clave válida si cumple con algún patrón. Es posible que desee utilizar esto desde dentro y fuera de la clase. Sin embargo, no quiero crear otra función global:

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

Prefiero agrupar este código con la clase a la que está asociado:

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'')


La razón más importante para usar un @classmethod es en un constructor alternativo que se pretende heredar. Esto puede ser muy útil en polimorfismo. Un ejemplo:

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()

Observe que Shape es una clase abstracta que define un método de clase from_square , ya que Shape no está realmente definido, realmente no sabe cómo derivarse de un Square por lo que simplemente devuelve una instancia predeterminada de la clase.

Las clases heredadas pueden definir sus propias versiones de este método:

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)

El uso le permite tratar polimórficamente todas estas clases desinstaladas

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

Esto está bien y muy bien, podría decir, pero ¿por qué no podría usar el @staticmethod para lograr este mismo comportamiento polimórfico?

class Circle(Shape): def __init__(self, radius=10): self.radius = radius @staticmethod def from_square(square): return Circle(radius=square.length/2)

La respuesta es que podrías, pero no obtienes los beneficios de la herencia porque se debe llamar a Circle explícitamente en el método. Es decir, si lo llamo desde una clase heredada sin anulación, todavía obtendría Circle cada vez.

Observe lo que se gana cuando defino otra clase de forma que realmente no tiene ninguna lógica from_square personalizada:

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

Aquí puede dejar el @classmethod undefined y usará la lógica de Shape.from_square mientras retiene quién es cls y devuelve la forma apropiada.

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


Métodos de ayuda para la inicialización:

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): ...


No sé, ¿algo así como los métodos de constructor con nombre?

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

Uso:

>>> x = UniqueIdentifier.produce() >>> y = FunkyUniqueIdentifier.produce() >>> x.name 0 >>> y.name Funky 1


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)