• python的实例方法、静态方法和类方法


    三种方法区别

    实例方法

        定义:第一个参数必须是实例对象,该参数名一般约定为self”,通过它来传递实例的属性和方法(也可以传类的属性和方法);

        调用:只能由实例对象调用。

    类方法

        定义:使用装饰器@classmethod。第一个参数必须是当前类对象,该参数名一般约定为cls”,通过它来传递类的属性和方法(不能传实例的属性和方法);

        调用:类和实例对象都可以调用。

    静态方法

        定义:使用装饰器@staticmethod。参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法;

        调用:类和实例对象都可以调用。

    class Foo(object):
        """类三种方法语法形式"""
     
        def instance_method(self):
            print("是类{}的实例方法,只能被实例对象调用".format(Foo))
     
        @staticmethod
        def static_method():
            print("是静态方法")
     
        @classmethod
        def class_method(cls):
            print("是类方法")
     
    foo = Foo()
    foo.instance_method()
    foo.static_method()
    foo.class_method()
    print('----------------')
    Foo.static_method()
    Foo.class_method()

    运行结果

    是类<class '__main__.Foo'>的实例方法,只能被实例对象调用
    是静态方法
    是类方法
    ----------------
    是静态方法
    是类方法

    说明:

    实例方法只能被实例对象调用,静态方法(由@staticmethod装饰的方法)、类方法(由@classmethod装饰的方法),可以被类或类的实例对象调用。

    实例方法,第一个参数必须要默认传实例对象,一般习惯用self。
    静态方法,参数没有要求。

    类方法,第一个参数必须要默认传类,一般习惯用cls。

    实例方法

    简而言之,实例方法就是类的实例能够使用的方法。这里不做过多解释。

    类方法

    使用装饰器@classmethod。

    原则上,类方法是将类本身作为对象进行操作的方法。假设有个方法,且这个方法在逻辑上采用类本身作为对象来调用更合理,那么这个方法就可以定义为类方法。另外,如果需要继承,也可以定义为类方法。

    如下场景:

    假设我有一个学生类和一个班级类,想要实现的功能为:
        执行班级人数增加的操作、获得班级的总人数;
        学生类继承自班级类,每实例化一个学生,班级人数都能增加;
        最后,我想定义一些学生,获得班级中的总人数。

    思考:这个问题用类方法做比较合适,为什么?因为我实例化的是学生,但是如果我从学生这一个实例中获得班级总人数,在逻辑上显然是不合理的。同时,如果想要获得班级总人数,如果生成一个班级的实例也是没有必要的。

    class ClassTest(object):
        __num = 0
    
        @classmethod
        def addNum(cls):
            cls.__num += 1
    
        @classmethod
        def getNum(cls):
            return cls.__num
    
        # 这里我用到魔术方法__new__,主要是为了在创建实例的时候调用累加方法。
        def __new__(self):
            ClassTest.addNum()
            return super(ClassTest, self).__new__(self)
    
    
    class Student(ClassTest):
        def __init__(self):
            self.name = ''
    
    a = Student()
    b = Student()
    print(ClassTest.getNum())

    静态方法

    使用装饰器@staticmethod。

    静态方法是类中的函数,不需要实例。静态方法主要是用来存放逻辑性的代码,逻辑上属于类,但是和类本身没有关系,也就是说在静态方法中,不会涉及到类中的属性和方法的操作。可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护。

    譬如,我想定义一个关于时间操作的类,其中有一个获取当前时间的函数。

    import time
    
    class TimeTest(object):
        def __init__(self, hour, minute, second):
            self.hour = hour
            self.minute = minute
            self.second = second
    
        @staticmethod
        def showTime():
            return time.strftime("%H:%M:%S", time.localtime())
    
    
    print(TimeTest.showTime())
    t = TimeTest(2, 10, 10)
    nowTime = t.showTime()
    print(nowTime)

    如上,使用了静态方法(函数),然而方法体中并没使用实例的属性和方法(但可以通过类名调用类属性和类方法)。若要获得当前时间的字符串时,并不一定需要实例化对象,此时对于静态方法而言,所在类更像是一种名称空间。其实,我们也可以在类外面写一个同样的函数来做这些事,但是这样做就打乱了逻辑关系,也会导致以后代码维护困难。

    静态方法、类方法使用区别或者说使用场景

    1、类方法用在模拟java定义多个构造函数的情况。

     由于python类中只能有一个初始化方法,不能按照不同的情况初始化类。

        # coding:utf-8
        class Book(object):
         
            def __init__(self, title):
                self.title = title
         
            @classmethod
            def class_method_create(cls, title):
                book = cls(title=title)
                return book
         
            @staticmethod
            def static_method_create(title):
                book= Book(title)
                return book
         
        book1 = Book("use instance_method_create book instance")
        book2 = Book.class_method_create("use class_method_create book instance")
        book3 = Book.static_method_create("use static_method_create book instance")
        print(book1.title)
        print(book2.title)
        print(book3.title)

    结果:

    use instance_method_create book instance
    use class_method_create book instance
    use static_method_create book instance

    特别说明,静态方法也可以实现上面功能,当静态方法每次都要写上类的名字,不方便。

    2、类中静态方法方法调用静态方法和类方法调用静态方法例子。

    下面的代码,静态方法调用另一个静态方法,如果改用类方法调用静态方法,可以让cls代替类,

    class Foo(object):
        X = 1
        Y = 2
    
        @staticmethod
        def averag(*mixes):  
            return sum(mixes) / len(mixes)
    
        @staticmethod
        def static_method():  # "静态方法中调用静态方法"
            print("静态方法中调用静态方法")
            return Foo.averag(Foo.X, Foo.Y)
    
        @classmethod
        def class_method(cls):  # 类方法中调用静态方法
            print("类方法中调用静态方法")
            return cls.averag(cls.X, cls.Y)

    结果:

    在静态方法中调用静态方法
    1
    在类方法中使用静态方法
    1

    3、继承类中的区别 

    从下面代码可以看出,如果子类继承父类的方法,子类覆盖了父类的静态方法,
    子类的实例继承了父类的static_method静态方法,调用该方法,还是调用的父类的方法和类属性。

    子类的实例继承了父类的class_method类方法,调用该方法,调用的是子类的方法和子类的类属性。

    class Foo(object):
        X = 1
        Y = 14
    
        @staticmethod
        def averag(*mixes):  # "父类中的静态方法"
            return sum(mixes) / len(mixes)
    
        @staticmethod
        def static_method():  # "父类中的静态方法"
            print("父类中的静态方法")
            return Foo.averag(Foo.X, Foo.Y)
    
        @classmethod
        def class_method(cls):  # 父类中的类方法
            print("父类中的类方法")
            return cls.averag(cls.X, cls.Y)
    
    
    class Son(Foo):
        X = 3
        Y = 5
    
        @staticmethod
        def averag(*mixes):  # "子类中重载了父类的静态方法"
            print("子类中重载了父类的静态方法")
            print( "666 ", mixes)return sum(mixes) / 3
    
    
    p = Son()
    print("result of p.averag(1,5)")
    print(p.averag(1, 5))
    print("result of p.static_method()")
    print(p.static_method())
    print("result of p.class_method()")
    print(p.class_method())

    结果如下:

    result of p.averag(1,5)
    子类中重载了父类的静态方法
    666  (1, 5)
    2.0
    result of p.static_method()
    父类中的静态方法
    7.5
    result of p.class_method()
    父类中的类方法
    子类中重载了父类的静态方法
    666  (3, 5)
    2.6666666666666665
  • 相关阅读:
    java 11 值得关注的新特性
    MessageDigest来实现数据加密
    LinkedList(JDK1.8)源码分析
    gradle配置统一管理
    Android 新架构组件 -- WorkManager
    RF使用ie浏览器访问页面,浏览器启动只显示This is the initial start page for the WebDriver server,页面访问失败
    jenkins配置RF构建结果显示
    jenkins配置QQ邮箱自动发送RF测试构建结果通知邮件
    RF变量列表类型@{}和${}列表类型的关系
    jekins构建通知邮件配置及邮件附件设置,jenkins构建通知邮件没有RF的log和report文件
  • 原文地址:https://www.cnblogs.com/fat-girl-spring/p/14986639.html
Copyright © 2020-2023  润新知