为什么我在Python中应该使用classmethod?

13

我正在Python的某个类中编写一个函数,人们建议我为这个函数添加一个@classmethod装饰器。

我的代码:

import random


class Randomize:
    RANDOM_CHOICE = 'abcdefg'

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

    def _randomize(self, random_chars=3):
        return ''.join(random.choice(self.RANDOM_CHOICE)
                       for _ in range(random_chars))

建议的更改:

    @classmethod
    def _randomize(cls, random_chars=3):
        return ''.join(random.choice(cls.RANDOM_CHOICE)
                       for _ in range(random_chars))

我几乎总是只使用_randomize函数。

我的问题是:向函数添加classmethod修饰器有什么好处?


7
这句话的意思是,这种方法不使用类的实例(通常称为 self)中的任何状态,这使其更加清晰明了。同时也意味着你可以在不创建实例的情况下对类进行测试。 - jonrsharpe
此外,如果这个类没有太多其他内容,最好使用一个函数和functools.partial()。也许。 - Markus Meskanen
1个回答

11
如果你看到_randomize方法,它并没有使用任何在init中声明的实例变量,但是它使用了一个类变量var,即RANDOM_CHOICE = 'abcdefg'
import random

class Randomize:
    RANDOM_CHOICE = 'abcdefg'

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

    def _randomize(self, random_chars=3):
        return ''.join(random.choice(self.RANDOM_CHOICE)
                       for _ in range(random_chars))

这意味着,您的方法可以存在而不是实例方法,并且您可以直接在类上调用它。

  Randomize._randomize()

现在的问题是:这种方法有什么优点吗?

  • 我认为有,您不必创建实例即可使用此方法,这将带来额外的开销。

ran = Randomize() // Extra steps
ran._randomize()   

你可以在这里了解更多关于类变量和实例变量的信息。


我想我还没有看到重点。如果您有使用案例,需要调用该方法而不需要类的实例,为什么不将该方法放在类外部呢? - ryanjdillon
1
@ryanjdillon 为什么不把那个方法放在类外面呢?嗯,因为那个方法很适合在那个类里使用,但你也可以在其他地方使用它。为什么要用 classmethod 而不是在其他地方使用 method 呢?因为它需要来自类的参数,此外它不需要来自实例的参数。当你需要从一个模块中获取资源,但又不想处理实例化类所带来的“浪费内存(泛化)”时,它就非常有用了。这就像为什么你需要 staticmethod?你不一定需要它,但把相关的东西放在一个地方更整洁。 - dmb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接