zoukankan      html  css  js  c++  java
  • python笔记60

    前言

    python 类里面常用的方法有3个:静态方法(@staticmethod),类方法(@classmethod)和实例方法(self)
    本篇讲解这3种方法在使用上有什么区别。

    函数

    先从函数说起,方法跟函数是有区别的,经常有人容易混淆,函数定义是def 关键字定义(外面没class)

    def fun():
        a = "hello"
        return a
    
    # 函数调用
    res = fun()
    print(res)
    

    函数调用使用函数名称后面加括号就能调用了

    实例方法(self)

    类里面的方法定义也是用def 关键字,注意在类里面叫方法了,不叫函数,定义的方法默认在括号里面加一个self参数。
    self 是类本身的实例对象,所以在看到def 定义的方法括号后面有self参数的叫实例方法。

    class A(object):
        count = 0
    
        def fun(self):
            b = "world"
            return b
    
    # A类不能直接调用fun
    # print(A.fun())
    a = A()
    print(a.fun())
    

    前面https://www.cnblogs.com/yoyoketang/p/15151723.html讲属性的时候说到过A类的属性和A()实例对象属性是不一样的。
    fun()里面带了self参数,那么它是实例方法,也就是A()实例对象的方法了,所以必须先实例化A()才能调用此方法。

    静态方法(@staticmethod)

    我们可以在函数里面写一个类

    def fun():
        a = "hello"
        
        class A(object):
            count = 0
        
            def fun(self):
                b = "world"
                return b
        return A
    

    于是会想到,在类里面是不是也可以写一个函数呢?于是就有了静态方法(@staticmethod),静态方法的出现就是为了在类里面可以写一个函数,当普通的函数去调用。
    定义静态方法需使用@staticmethod装饰器,并且括号后面不需要self参数了。

    # 作者-上海悠悠 QQ交流群:717225969 
    # blog地址 https://www.cnblogs.com/yoyoketang/
    
    
    class A(object):
        count = 0
    
        def fun(self):
            b = "world"
            return b
    
        @staticmethod
        def start():
            print("start-----")
    
    # 不用实例化也能调用
    A.start()
    # 实例化也能调用
    a = A()
    a.start()
    

    静态方法不需要实例化可以直接调用,实例化后也能调用,可以理解成函数。

    类方法(@classmethod)

    类里面有2个概念,属性和方法。
    前面讲到A类和A()实例对象的属性是不一样的,比如

    • A类只要count属性
    • A()实例对象的属性是__init__里面的age和name,并且包含A类属性count
    class A(object):
        count = 0
    
        def __init__(self):
            self.age = 18
            self.name = "yoyo"
    # A只有count属性
    print(A.count)
    
    # A() 实例化对象
    a = A()
    print(a.count)
    print(a.name)
    print(a.age)
    

    既然已经知道了A类的属性和A()实例对象属性是不一样的,再回到前面的实例方法概念上,实例方法是A()实例对象的方法。
    既然A()实例对象有实例方法,那么A类当然也有类方法的概念了,于是可以在方法上加上@classmethod装饰器声明它是类方法,并且括号第一个参数cls是指类本身

    # 作者-上海悠悠 QQ交流群:717225969 
    # blog地址 https://www.cnblogs.com/yoyoketang/
    
    
    class A(object):
        count = 0
    
        def fun(self):
            b = "world"
            return b
    
        @staticmethod
        def start():
            print("start-----")
    
        @classmethod
        def create(cls):
            print("create--------")
    
    # 不需要实例化,类名称直接调用类方法
    A.create()
    # 实例化也能调用类方法
    a = A()
    a.create()
    

    类方法使用场景

    实例方法和静态方法小伙伴们应该是经常用的,类方法这个概念本身比较难懂,就算看懂了也不知道如何用到具体场景上,在网上搜到一个案例讲解的挺好的。
    看下面的定义的一个时间类:

    class DataTest(object):
        day = 0
        month = 0
        year = 0
    
        def __init__(self, year=0, month=0, day=0):
            self.day = day
            self.month = month
            self.year = year
    
        def out_date(self):
            print("year :", self.year)
            print("month :", self.month)
            print("day :", self.day)
    
    t = DataTest(2021, 8, 18)
    t.out_date()   
    

    输出:

    year : 2021
    month : 8
    day : 18
    

    如果用户输入的是 "2016-8-1" 这样的字符格式,那么就需要调用Date_test 类前做一下处理:

    string_date = '2018-8-18'
    year, month, day = map(int, string_date.split('-'))
    s = DataTest(year, month, day)
    print(s.out_date())
    

    先把‘2018-8-18’ 分解成 year,month,day三个变量,然后转成int,再调用DataTest(year, month, day) 也很符合期望。
    那我可不可以把这个字符串处理的函数放到 DateTest 类当中呢?
    那么@classmethod 就开始出场了

    class DataTest(object):
        day = 0
        month = 0
        year = 0
    
        def __init__(self, year=0, month=0, day=0):
            self.day = day
            self.month = month
            self.year = year
    
        def out_date(self):
            print("year :", self.year)
            print("month :", self.month)
            print("day :", self.day)
    
        @classmethod
        def get_data(cls, string_date):
            """处理'2018-8-18'字符格式"""
            year, month, day = map(int, string_date.split('-'))
            return cls(year, month, day)
    

    定义一个get_data类方法,处理完字符串后返回这个类的实例对象

    r = DataTest.get_data('2018-8-18')
    r.out_date()
    

    这样同样可以达到实例化的效果,于是就兼容了前面的代码了
    参考资料https://www.zhihu.com/question/20021164

  • 相关阅读:
    20200726 千锤百炼软工人第二十一天
    20200725 千锤百炼软工人第二十天
    20200724 千锤百炼软工人第十九天
    20200723 千锤百炼软工人第十八天
    20200722 千锤百炼软工人第十七天
    20200721 千锤百炼软工人第十六天
    剑指Offer_#64_求1+2+…+n
    剑指Offer_#63_股票的最大利润
    剑指Offer_#62_圆圈中最后剩下的数字
    剑指Offer_#61_扑克牌中的顺子
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/15159377.html
Copyright © 2011-2022 走看看