我读过Python中的类方法是做什么的?但那篇文章中的例子很复杂。我正在寻找一个清晰、简单、基本的例子,说明Python中类方法的特定用例。
您能举出一个小型的、特定的用例吗?
初始化的助手方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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): ... |
因此,
如。
1 2 | >>> dict.fromkeys("12345") {'1': None, '3': None, '2': None, '5': None, '4': None} |
比如命名构造函数方法?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 |
用法:
1 2 3 4 5 6 | >>> x = UniqueIdentifier.produce() >>> y = FunkyUniqueIdentifier.produce() >>> x.name 0 >>> y.name Funky 1 |
我发现,在不需要类的实例来使用代码的情况下,我最常使用
例如,我可能有一个数据结构,它只在键符合某种模式时才认为键是有效的。我可能会在课堂内外用到它。但是,我不想再创建另一个全局函数:
1 2 3 | def foo_key_is_valid(key): # code for determining validity here return valid |
我更愿意将这段代码与它关联的类进行分组:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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') |
使用
1 2 3 4 5 6 7 | 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() |
注意,
然后允许继承的类定义它们自己的版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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) |
这种用法允许您多态地处理所有这些未实例化的类
1 2 3 | square = Square(3) for polymorphic_class in (Square, Rectangle, RightTriangle, Circle): this_shape = polymorphic_class.from_square(square) |
您可能会说这一切都很好,但是为什么我不能使用as
1 2 3 4 5 6 7 | class Circle(Shape): def __init__(self, radius=10): self.radius = radius @staticmethod def from_square(square): return Circle(radius=square.length/2) |
答案是可以,但是不能获得继承的好处,因为
请注意,当我定义了另一个形状类,实际上没有任何自定义from_square逻辑时,得到了什么:
1 2 3 4 5 | 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 |
这里可以不定义
1 2 3 | square = Square(3) for polymorphic_class in (Square, Rectangle, RightTriangle, Circle, Hexagon): this_shape = polymorphic_class.from_square(square) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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) |