Python 基础 —— @classmethod 与 @staticmethod 的意义及用途

来源:互联网 发布:仙界网络直播间无弹窗 编辑:程序博客网 时间:2024/05/21 17:33

Meaning of @classmethod and @staticmethod for beginner?

——————————

@classmethod

意味着:当调用此方法时,我们将该类作为第一个参数传递,而不是该类的实例(正如我们通常使用的方法)。这意味着您可以使用该方法中的类及其属性,而不是特定的实例。

@staticmethod

意味着:当调用此方法时,我们不会将类的实例传递给它(正如我们通常使用的方法)。这意味着你可以在一个类中放置一个函数,但是你无法访问该类的实例(当你的方法不使用实例时这很实用)。

——————————

虽然classmethod和staticmethod是非常相似的,但两个实体的使用有一点区别:classmethod必须具有对类对象的引用作为第一个参数,而staticmethod根本不能有任何参数。

我们来看看在实例中说的一切。

样板

让我们假设一个课程的例子,处理日期信息(这将是我们的样板做饭):

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

这个类显然可以用于存储有关某些日期的信息(没有时区信息;假设所有日期都以UTC格式显示)。

这里我们有__init__,一个Python类实例的典型的初始化器,它接收参数作为一个典型的实例方法,具有第一个非可选参数(self),它保存对新创建的实例的引用。


classmethod

我们有一些任务可以很好地使用类方法。

假设我们要创建大量的Date类实例,其日期信息来自外部源码,作为下一个格式的字符串(’dd-mm-yyyy’)编码。我们必须在项目的源代码的不同地方这样做。

所以我们必须做的是:

解析一个字符串来接收日,月和年三个整数变量或由该变量组成的3项元组。
通过将这些值传递给初始化调用实例化日期。
这将是:

为此,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 date1date2 = Date.from_string('11-09-2012')

我们来看看上面的实现,看看这里有哪些优点?

我们在一个地方实现了日期字符串解析,现在可以重用。

封装在这里工作正常(如果您认为您可以在其他地方将字符串解析为单个功能,则该解决方案可以更好地适应OOP范例)。

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

所以,从静态方法的使用可以看出,我们无法访问类的内容 - 它基本上只是一个函数,在语法上就像一个方法一样,但不能访问该对象,而且是内部的(字段和另一个方法),而classmethod则。

———-

class MethodTest(object):    def __init__(self, input_string):        self.my_string = input_string    def normalMethod(self):        print('this is normal method ---- {}'.format(self.my_string))    @classmethod    def classMethod(cls, kkk):        # print('class method', cls)        method_test_instance = cls(kkk.split()[0])        print('this is the usage of classmethod ! you can see it !!! ---- {}'.format(method_test_instance.my_string))        print(type(method_test_instance))    @staticmethod    def staticMethod():        print('this is static method')my_test = MethodTest('hello world')print(type(my_test))my_test.normalMethod()MethodTest.classMethod('hello world')MethodTest.staticMethod()
<class '__main__.MethodTest'>this is normal method ---- hello worldthis is the usage of classmethod ! you can see it !!! ---- hello<class '__main__.MethodTest'>this is static methodProcess finished with exit code 0
class MethodTest(object):    def __init__(self, input_string):        self.my_string = input_string    def normalMethod(self):        print('this is normal method ---- {}'.format(self.my_string))    @classmethod    def classMethod(cls, kkk):        # print('class method', cls)        method_test_instance = cls(kkk.split()[0])        print('this is the usage of classmethod ! you can see it !!! ---- {}'.format(method_test_instance.my_string))        print(type(method_test_instance))    @staticmethod    def staticMethod():        print('this is static method')my_test = MethodTest('hello world')print(type(my_test))my_test.normalMethod()MethodTest.classMethod('hello world')MethodTest.staticMethod()### class Date(object):##     def __init__(self, day=0, month=0, year=0):#         self.day = day#         self.month = month#         self.year = year##     @classmethod#     def from_string(cls, date_as_string):#         day, month, year = map(int, date_as_string.split('-'))#         date1 = cls(day, month, year)#         return date1##     @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### date2 = Date.from_string('11-09-2012')# print(date2)# print(type(date2))## # usage:# is_date = Date.is_date_valid('11-09-2012')# print(is_date)# print(type(is_date))
阅读全文
0 0
原创粉丝点击