什么时候应该使用@classmethod?什么时候应该使用def method(self)? [英] When should I use @classmethod and when def method(self)?

查看:338
本文介绍了什么时候应该使用@classmethod?什么时候应该使用def method(self)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在集成我以前从未使用过的Django应用程序时,我发现了用于定义类中函数的两种不同方法.作者似乎非常有意地使用了它们.第一个是我自己经常使用的:

While integrating a Django app I have not used before, I found two different ways used to define functions in classes. The author seems to use them both very intentionally. The first one is one I myself use a lot:

class Dummy(object):

    def some_function(self,*args,**kwargs):
        do something here
        self is the class instance

另一个是我不使用的,主要是因为我不知道何时使用它以及用于什么用途

The other one is one I do not use, mostly because I do not understand when to use it, and what for:

class Dummy(object):

    @classmethod
    def some_function(cls,*args,**kwargs):
        do something here
        cls refers to what?

在Python文档中,classmethod装饰器的解释如下:

In the Python docs the classmethod decorator is explained with this sentence:

一个类方法接收该类作为隐式第一个参数,只是 就像实例方法接收实例一样.

A class method receives the class as implicit first argument, just like an instance method receives the instance.

所以我想cls是指Dummy本身(class,而不是实例).我不完全理解为什么会这样,因为我总是可以这样做:

So I guess cls refers to Dummy itself (the class, not the instance). I do not exactly understand why this exists, because I could always do this:

type(self).do_something_with_the_class

这仅仅是为了清楚起见,还是我想念最重要的部分:没有它就无法完成的怪异而令人着迷的事情?

Is this just for the sake of clarity, or did I miss the most important part: spooky and fascinating things that couldn't be done without it?

推荐答案

您的猜测是正确的-您了解如何 classmethod的工作.

Your guess is correct - you understand how classmethods work.

为什么可以在实例或类上调用这些方法(在两种情况下,类对象都将作为第一个参数传递):

The why is that these methods can be called both on an instance OR on the class (in both cases, the class object will be passed as the first argument):

class Dummy(object):

    @classmethod
    def some_function(cls,*args,**kwargs):
        print cls

#both of these will have exactly the same effect
Dummy.some_function()
Dummy().some_function()

关于在实例上使用这些方法:在实例上调用类方法至少有两个主要用途:

On the use of these on instances: There are at least two main uses for calling a classmethod on an instance:

  1. self.some_function()将以实际的self类型调用some_function的版本,而不是出现该调用的类(如果重命名该类,则无需引起注意);和
  2. 在实现某些协议必需使用some_function的情况下,但仅在调用类对象时有用.
  1. self.some_function() will call the version of some_function on the actual type of self, rather than the class in which that call happens to appear (and won't need attention if the class is renamed); and
  2. In cases where some_function is necessary to implement some protocol, but is useful to call on the class object alone.

staticmethod 的区别:定义不访问实例数据的方法的另一种方式称为staticmethod.这样就创建了一个根本不接收隐式第一个参数的方法.因此,将不会传递有关调用它的实例或类的任何信息.

The difference with staticmethod: There is another way of defining methods that don't access instance data, called staticmethod. That creates a method which does not receive an implicit first argument at all; accordingly it won't be passed any information about the instance or class on which it was called.

In [6]: class Foo(object): some_static = staticmethod(lambda x: x+1)

In [7]: Foo.some_static(1)
Out[7]: 2

In [8]: Foo().some_static(1)
Out[8]: 2

In [9]: class Bar(Foo): some_static = staticmethod(lambda x: x*2)

In [10]: Bar.some_static(1)
Out[10]: 2

In [11]: Bar().some_static(1)
Out[11]: 2

我发现它的主要用途是将现有函数(不会收到self)改编为类(或对象)上的方法.

The main use I've found for it is to adapt an existing function (which doesn't expect to receive a self) to be a method on a class (or object).

这篇关于什么时候应该使用@classmethod?什么时候应该使用def method(self)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆