资讯专栏INFORMATION COLUMN

【译】python 静态方法和类方法的区别

Crazy_Coder / 1938人阅读

摘要:尽管和非常相似,但在用法上依然有一些明显的区别。所以,从静态方法的使用中可以看出,我们不会访问到本身它基本上只是一个函数,在语法上就像一个方法一样,但是没有访问对象和它的内部字段和其他方法,相反会访问,会访问。

python staticmethod and classmethod

Though classmethod and staticmethod are quite similar, there"s a slight difference in usage for both entities: classmethod must have a reference to a class object as the first parameter, whereas staticmethod can have no parameters at all.

Let"s look at all that was said in real examples.

尽管 classmethod 和 staticmethod 非常相似,但在用法上依然有一些明显的区别。classmethod 必须有一个指向 类对象 的引用作为第一个参数,而 staticmethod 可以没有任何参数。

让我们看几个例子。

例子 - Boilerplate

Let"s assume an example of a class, dealing with date information (this is what will be our boilerplate to cook on):

class Date(object):

    def __init__(self, day=0, month=0, year=0):
        self.day = day
        self.month = month
        self.year = year

This class obviously could be used to store information about certain dates (without timezone information; let"s assume all dates are presented in UTC).

很明显,这个类的对象可以存储日期信息(不包括时区,假设他们都存储在 UTC)。

Here we have __init__, a typical initializer of Python class instances, which receives arguments as a typical instancemethod, having the first non-optional argument (self) that holds reference to a newly created instance.

这里的 init 方法用于初始化对象的属性,它的第一个参数一定是 self,用于指向已经创建好的对象。

Class Method

We have some tasks that can be nicely done using classmethods.

Let"s assume that we want to create a lot of Date class instances having date information coming from outer source encoded as a string of next format ("dd-mm-yyyy"). We have to do that in different places of our source code in project.

利用 classmethod 可以做一些很棒的东西。

比如我们可以支持从特定格式的日期字符串来创建对象,它的格式是 ("dd-mm-yyyy")。很明显,我们只能在其他地方而不是 init 方法里实现这个功能。

So what we must do here is:
Parse a string to receive day, month and year as three integer variables or a 3-item tuple consisting of that variable.
Instantiate Date by passing those values to initialization call.
This will look like:

大概步骤:

解析字符串,得到整数 day, month, year。

使用得到的信息初始化对象

代码如下

day, month, year = map(int, string_date.split("-"))
date1 = Date(day, month, year)

理想的情况是 Date 类本身可以具备处理字符串时间的能力,解决了重用性问题,比如添加一个额外的方法。

For this purpose, C++ has such feature as overloading, but Python lacks that feature- so here"s when classmethod applies. Lets create another "constructor".

C++ 可以方便的使用重载来解决这个问题,但是 python 不具备类似的特性。 所以接下来我们要使用 classmethod 来帮我们实现。

@classmethod
  def from_string(cls, date_as_string):
  day, month, year = map(int, date_as_string.split("-"))
  date1 = cls(day, month, year)
  return date1


date2 = Date.from_string("11-09-2012")

Let"s look more carefully at the above implementation, and review what advantages we have here:

We"ve implemented date string parsing in one place and it"s reusable now.
Encapsulation works fine here (if you think that you could implement string parsing as a single function elsewhere, this solution fits OOP paradigm far better).
cls is an object that holds class itself, not an instance of the class. It"s pretty cool because if we inherit our Date class, all children will have from_string defined also.

让我们在仔细的分析下上面的实现,看看它的好处。

我们在一个方法中实现了功能,因此它是可重用的。 这里的封装处理的不错(如果你发现还可以在代码的任意地方添加一个不属于 Date 的函数来实现类似的功能,那很显然上面的办法更符合 OOP 规范)。 cls 是一个保存了 class 的对象(所有的一切都是对象)。 更妙的是, Date 类的衍生类都会具有 from_string 这个有用的方法。

Static method

What about staticmethod? It"s pretty similar to classmethod but doesn"t take any obligatory parameters (like a class method or instance method does).

Let"s look at the next use case.

We have a date string that we want to validate somehow. This task is also logically bound to Date class we"ve used so far, but still doesn"t require instantiation of it.

Here is where staticmethod can be useful. Let"s look at the next piece of code:

staticmethod 没有任何必选参数,而 classmethod 第一个参数永远是 cls, instancemethod 第一个参数永远是 self。

@staticmethod
def is_date_valid(date_as_string):
  day, month, year = map(int, date_as_string.split("-"))
  return day <= 31 and month <= 12 and year <= 3999

# usage:
is_date = Date.is_date_valid("11-09-2012")

So, as we can see from usage of staticmethod, we don"t have any access to what the class is- it"s basically just a function, called syntactically like a method, but without access to the object and it"s internals (fields and another methods), while classmethod does.

所以,从静态方法的使用中可以看出,我们不会访问到 class 本身 - 它基本上只是一个函数,在语法上就像一个方法一样,但是没有访问对象和它的内部(字段和其他方法),相反 classmethod 会访问 cls, instancemethod 会访问 self。

参考

Meaning of @classmethod and @staticmethod for beginner?

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/40935.html

相关文章

  • 】函数组件和类组件有什么不同?

    摘要:但是,你可能已经注意到,当你试图通过指定依赖数组来优化时,可能会遇到带有过时闭包的错误。这是否意味着闭包是问题所在我不这么认为。到目前为止,我所看到的所有情况下,过时的闭包问题都是由于错误地假设函数不更改或总是相同而发生的。 原文链接:https://overreacted.io/how-ar... 在很长一段时间内,标准答案是class components提供更多的特性(像sta...

    gself 评论0 收藏0
  • Python方法静态方法之间区别

      小编写这篇文章的主要目的,是讲述一下关于Python的一些小技巧,包括类方法与静态方法之间,存在一些什么区别呢?怎么从真正的意义上去理解关于其不同之间的区别呢?下面就给大家详细的解答下。  前言  在python的类中不仅可以有methods,还可以有变量,这些变量称为类属性,例如如下代码中Book类的TYPES即为类属性。  类中的方法分为3类:  1.实例方法instance method...

    89542767 评论0 收藏0
  • python函数和类一些研究

    摘要:与通常认为实例方法是的,而类方法是的,这种说法也没错,只是对于不同类型变量来说,结果是不同的测试一下结果显示的都是直接从类访问,结果这个实例方法显示的是。可以知道的意义并不是始终不变的,对于不同的对象来说意义并不一样。 bound与unbound 通常认为实例方法是bound的,而类方法是unbound的,这种说法也没错,只是对于不同类型变量来说,结果是不同的 class A(obje...

    Wildcard 评论0 收藏0
  • []Java和Python——应该先学习哪种编程语言

    摘要:和是目前两种非常流行且功能强大的编程语言。初级程序员常常感到困惑,最常被问到的问题就是应该学习还是,是不是容易上手,应该推荐给初学者学习什么样的编程语言等等。在学习任何编程语言之前,你必须知道它们之间的区别。 Java和Python是目前两种非常流行且功能强大的编程语言。初级程序员常常感到困惑,最常被问到的问题就是应该学习Java还是Python,Python是不是容易上手,应该推荐给...

    honmaple 评论0 收藏0
  • [] 属性访问、特性和描述符 1

    摘要:许多程序员发现赋值语句比方法函数看起来更清晰。自从和属性的创建来自,我们必须经常定义特性使用如下代码这允许我们用一条简单的语句添加一张牌到手中像下面这样前面的赋值语句有一个缺点,因为它看起来像一张牌替代了所有的牌。 注:原书作者 Steven F. Lott,原书名为 Mastering Object-oriented Python 对象就是一些特性的集合,包括方法和属性。object...

    褰辩话 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<