zoukankan      html  css  js  c++  java
  • Python中的 staticmethod 和 classmethod

    众所周知,类是创建实例的模板,而实例是一个个具体的对象,各个实例拥有的数据相互独立、互不影响。

    在类中定义的函数称为方法,主要有三种:实例方法、类方法、静态方法

    class A:
    
        def instance_method(self, n):
            print('self', self)
    
        @classmethod
        def class_method(cls, n):
            print('cls', cls)
    
        @staticmethod
        def static_method():
            print('this is a static method')
    

    上面类 A 定义的三个方法分别是实例方法、类方法、静态方法,下面我们来详细分析

    实例方法

    不带装饰器的实例方法在类定义中是最常见的:

    定义中,传入的第一个参数必须是 self,表示实例本身,在其中可使用 self.attr 获取实例的属性。

    a = A()
    a.instance_method(2)
    print(A.bar)
    print(a.bar)
    

    下面是程序运行结果:

    self <__main__.A object at 0x0000028554C87E48>
    grg
    grg
    

    当我们创建了实例 a 之后,调用 a.instance_method(2) 时,实例 a 会被自动传入函数作为 self 参数。

    如果我们调用 A.instance_method(2) 时会发生什么呢?即,类能不能调用实例方法?

    Traceback (most recent call last):
      File "I:Program CodePython	est2.py", line 32, in <module>
        A.instance_method(2)
    TypeError: instance_method() missing 1 required positional argument: 'n'
    

    可以看到,数字 2 被传入 self 参数了,所以才会提示缺少一个位置参数 n,所以,实例方法不能由类调用。

    顺便提一句,属性也分实例属性和类属性,上例直接定义的是类属性,类和类实例都可以访问。类中定义的方法也可以无限制访问这个类属性。

    通过 __init__(self,attr) 定义的是实例属性,只有实例能访问,类不能访问。类中定义的属性只有传进了 self 参数的方法(通常就是实例方法)可访问。

    classmethod

    无需实例化,但与实例方法第一个参数必须是 self 类似,类方法第一个参数表示类自身的 cls 参数,可以来调用类的属性、类的方法、类的实例化对象等

    a.class_method(2)
    A.class_method(2)
    

    观察上面代码的运行结果:

    cls <class '__main__.A'>
    cls <class '__main__.A'>
    

    可知,类方法既可以由类调用,也可以由实例调用。

    再来看一个例子:

    class Book(object):
        def __init__(self, title):
            self.title = title
    
        @classmethod
        def create(cls, title):
            book = cls(title)
            return book
    
    
    book1 = Book('A song of Ice and Fire')
    book2 = Book.create('The Marvel')
    print(book1.title)
    print(book2.title)
    

    运行结果如下:

    A song of Ice and Fire
    The Marvel
    

    上面,类方法创建了一个类实例。

    staticmethod

    无需 self 参数,无需 cls 参数,直接声明一个静态方法,可无需实例化,直接由类调用,也可实例化后调用。

    带 staticmethod 装饰器定义的就是静态方法,与普通函数没有区别,可以不加参数,可以加任意参数,不必传入 self ,既可以由实例调用,也可以由类调用。

    A.static_method()
    a.static_method()
    

    运行结果如下:

    this is a static method
    this is a static method
    

    总结

    实例方法只能由实例调用,类方法和静态方法可以由实例或类调用。

  • 相关阅读:
    Java I/O基础
    Python基础篇(九)
    Python基础篇(八)
    thinkphp5中Indirect modification of overloaded element of XXX has no effect的解决办法
    关于json_encode转义斜杠的问题
    [thinkexceptionErrorException] glob() has been disabled for security reasons
    CentOS7 安装svn
    -bash: /usr/bin/yum: /usr/bin/python: bad interpreter: No such file or directory
    php在线编辑本地文件方法共享
    python一些不错的东西
  • 原文地址:https://www.cnblogs.com/fan-1994716/p/13133443.html
Copyright © 2011-2022 走看看