• (译文)Python中的staticmethod与classmethod


    原文是stackoverflow的一则高票回答,原文链接
    可能之前也有人翻译过,但是刚好自己也有疑惑,所以搬运一下,个人水平有限所以可能翻译存在误差,欢迎指正(如侵删)。


    尽管classmethodstaticmethod非常的相似,但是两者在具体的使用上还是有着细微的差别:classmethod必须使用类对象作为第一个参数,而staticmethod则可以不传递任何参数。

    让我们通过实际的例子来看看。

    样板

    让我们假设有处理日期信息的类:

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

    这个类很显然可以被用来存储某些日期信息(不考虑时区信息;让我们假设所有的日期都用UTC表示)

    这里定义了__init__,典型的类实例初始化方法,它作为典型的instancemethod接受参数,其中第一个传递的必要参数是新建的实例本身。

    类方法

    有一些可以通过使用classmethod很好解决的任务。

    假设我们有很多('dd-mm-yyyy')格式字符串的日期信息,想要把它们创建成Date类实例。我们不得不在项目的不同地方做这些事情。

    所以我们必须要做到:

    1. 分析得到的年月日字符串,把它们转化成三个整形变量或者拥有三个元素的元组的变量。
    2. 通过传递这些值实例化Date

    得到:

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

    C++拥有重载的特性可以达到这种目的,但是Python缺乏此类特性。所以,python使用classmethod的方式。让我们尝试一种另类的构造函数。

        @classmethod
        def from_string(cls, date_as_string):
            day, month, year = map(date_as_string.split('-'))
            date1 = cls(day, month, year)
            return date1
    
    date2 = Date.from_string('11-09-2012')
    

    进一步分析一下以上代码的执行,以及它的优势:

    1.在一个地方解析日期字符串并且重复使用它。
    2.做到很好的封装(相对于把执行字符串解析作为一个单独的函数在任何地方执行,这里使用的方法更符合OOP的范式)
    3.cls表示类对象,而不是类实例。这样很酷,因为如果我们继承Date类,那么所有的子类也都将拥有from_string这个方法。

    静态方法

    那么staticmethod又是什么呢?它和classmethod非常的相似,但是不强制要求传递参数(但是做的事与类方法或实例方法一样)。

    让我们来看一个使用的例子。

    我们有一个日期字符串需要以某种方式验证。这个任务与之前一样要定义在Date类内部,但是不要求实例化它。

    静态方法在这种情况下就非常有用。看一下下面这个代码片段:

        @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
        
        is_date = Date.is_date_valid('11-09-2012')
    

    现在正如我们了解到的staticmethod的使用,我们不需要访问它所属的类,它本质上就是一个函数,调用方式和调用函数一样,不同的是它不关注对象和对象内部属性。

  • 相关阅读:
    js-20170816-Date对象
    js-20170804-Math对象
    js-20170619-string对象
    微信web开发者工具
    前端开发指南
    接口调试工具DHC
    CSS预处理器
    Weex
    Vue.js
    hbuilder
  • 原文地址:https://www.cnblogs.com/agnewee/p/5653936.html
Copyright © 2020-2023  润新知