Python类方法的示例用例是什么?

cof*_*der 59 python class class-method

我已经阅读了Python中的什么类方法?但那篇文章中的例子很复杂.我正在寻找Python中类方法的特定用例的清晰,简单,简单的例子.

您能说出一个小的,具体的示例用例,其中Python类方法将是该工作的正确工具吗?

ani*_*haw 47

帮助初始化方法:

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):
       ...
Run Code Online (Sandbox Code Playgroud)

  • 实际上,提供替代构造函数是"classmethod"的经典用例.与他们的`staticmethod`等价物不同,它们与子类很好地配合. (6认同)

Joh*_*ooy 28

__new__是一个非常重要的课堂方法.这是实例通常来自的地方

所以dict()呼吁dict.__new__当然,也有使http://stardict.sourceforge.net/Dictionaries.php下载有时另一种方便的方法是在类方法dict.fromkeys()

例如.

>>> dict.fromkeys("12345")
{'1': None, '3': None, '2': None, '5': None, '4': None}
Run Code Online (Sandbox Code Playgroud)


jul*_*icz 19

我不知道,像命名构造函数方法?

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
Run Code Online (Sandbox Code Playgroud)

用法:

>>> x = UniqueIdentifier.produce()
>>> y = FunkyUniqueIdentifier.produce()
>>> x.name
0
>>> y.name
Funky 1
Run Code Online (Sandbox Code Playgroud)


sam*_*ias 10

我发现我最常用于@classmethod将一段代码与一个类相关联,以避免创建一个全局函数,以防我不需要该类的实例来使用该代码.

例如,我可能有一个数据结构,如果它符合某种模式,它只考虑一个有效的密钥.我可能想从课堂内外使用它.但是,我不想创建另一个全局函数:

def foo_key_is_valid(key):
    # code for determining validity here
    return valid
Run Code Online (Sandbox Code Playgroud)

我更倾向于将这个代码与它关联的类组合在一起:

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')
Run Code Online (Sandbox Code Playgroud)

  • 这个用例听起来更像静态方法而不是类方法.如果你的方法没有使用cls参数,你应该使用@staticmethod. (14认同)

kra*_*yzk 10

使用a的最大原因@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()
Run Code Online (Sandbox Code Playgroud)

请注意,这Shape是一个定义类方法的抽象类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)
Run Code Online (Sandbox Code Playgroud)

该用法允许您以多态方式处理所有这些未实例化的类

square = Square(3)
for polymorphic_class in (Square, Rectangle, RightTriangle, Circle):
    this_shape = polymorphic_class.from_square(square)
Run Code Online (Sandbox Code Playgroud)

你可能会说这很好,但我为什么不能用它@staticmethod来完成同样的多态行为:

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

    @staticmethod
    def from_square(square):
        return Circle(radius=square.length/2)
Run Code Online (Sandbox Code Playgroud)

答案是你可以,但你没有得到继承的好处,因为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
Run Code Online (Sandbox Code Playgroud)

在这里你可以保留@classmethod未定义的,它将使用逻辑,Shape.from_square同时保留谁cls是并返回适当的形状.

square = Square(3)
for polymorphic_class in (Square, Rectangle, RightTriangle, Circle, Hexagon):
    this_shape = polymorphic_class.from_square(square)
Run Code Online (Sandbox Code Playgroud)