Каков пример использования для Python classmethod?
Я читал, что такое методы класса в Python? но примеры в этом посте сложны. Я ищу ясный, простой, голый пример конкретного случая использования для classmethods в Python.
можете ли вы назвать небольшой, конкретный пример использования, где Python classmethod будет правильным инструментом для работы?
6 ответов:
вспомогательные методы для инициализации:
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): ...
хорошо
__new__является довольно важным classmethod. Это где экземпляры обычно приходят изтак
dict()звонкиdict.__new__конечно, но есть еще один удобный способ сделать дикт иногда, который является classmethoddict.fromkeys()например.
>>> dict.fromkeys("12345") {'1': None, '3': None, '2': None, '5': None, '4': None}
Я не знаю, что-то вроде названные методы конструктор?
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использование:
>>> x = UniqueIdentifier.produce() >>> y = FunkyUniqueIdentifier.produce() >>> x.name 0 >>> y.name Funky 1
Я считаю, что я чаще всего использовать
@classmethodчтобы связать фрагмент кода с классом, чтобы избежать создания глобальной функции, в тех случаях, когда мне не требуется экземпляр класса для использования кода.например, у меня может быть структура данных, которая считает ключ допустимым только в том случае, если он соответствует некоторому шаблону. Я могу использовать это внутри и вне класса. Однако я не хочу создавать еще одну глобальную функцию:
def foo_key_is_valid(key): # code for determining validity here return validЯ бы предпочел группу этот код с классом, с которым он связан:
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')
самая большая причина для использования
@classmethodв другой конструктор, который предназначен для наследования. Это может быть очень полезно в полиморфизме. Пример: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()обратите внимание, что
Shape- это абстрактный класс, который определяет classmethod вfrom_squareСShapeна самом деле не определен, он действительно не знает, как вывести себя изSquareтак он просто возвращает экземпляр по умолчанию класса.наследуемые классы затем можно определить их собственные версии этого метода:
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)использование позволяет обрабатывать все эти удаленные классы полиморфно
square = Square(3) for polymorphic_class in (Square, Rectangle, RightTriangle, Circle): this_shape = polymorphic_class.from_square(square)это все прекрасно и денди вы могли бы сказать, но почему я не мог просто использовать как
@staticmethodдля достижения такого же полиморфного поведения:class Circle(Shape): def __init__(self, radius=10): self.radius = radius @staticmethod def from_square(square): return Circle(radius=square.length/2)ответ заключается в том, что вы могли бы, но вы не получаете преимущества наследования, потому что
Circleдолжен быть вызван явно в методе. То есть, если я это называю из унаследованного класса без переопределения я все равно получуCircleкаждый раз.обратите внимание, что получается, когда я определяю другой класс формы, который на самом деле не имеет никакой пользовательской логики from_square:
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здесь вы можете оставить
@classmethodundefined и он будет использовать логику отShape.from_squareпри сохранении, ктоclsis и возвращает соответствующую форму.square = Square(3) for polymorphic_class in (Square, Rectangle, RightTriangle, Circle, Hexagon): this_shape = polymorphic_class.from_square(square)
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)
Comments