python类的实例方法\静态方法\类方法区别解析(附代码)

前言

搞了好久python,一直搞得不太清楚这几种类的方法,今天花时间好好测试一下,算是弄懂点皮毛吧。

三种方法的不同

先剽窃个图看一下

可以看到,实例是三种方法都可以调用的,而类只可以调用两种。所以这些方法的使用就是看你是否要让类不需要通过实例来调用方法(类方法和静态方法都不需要实例化成对象即可调用),而类方法和静态方法的区别就是你是否要在该方法引用类的属性或者其他类的类方法。
可能还是看不太懂吧,继续看。

实例

这其实是参考stackoverflow问答里一位大神的回复稍微改了改

  • 先解析下这脚本干啥的:
    就是有个类叫Data_test,然后实例化i = Data_test('2016','1','1')它能把结果按格式输出出来,打印年月日,但偏偏有的人比较贱,非要往里传一个"2016-1-1"这样的字符串,我们的类该怎么办呢。

    class Data_test(object):
        day=0
        month=0
        year=0
        forclass = 250
        def __init__(self,year=0,month=0,day=0):
            self.day=day
            self.month=month
            self.year=year
    
        @classmethod
        def get_date_class(cls,data_as_string): # 可以传参,cls即为类自身
            year,month,day=map(int,data_as_string.split('-'))
            return cls(year,month,cls.forclass)  # 因为类方法可以传参一个cls参数,所以可以调用类的相关信息,而静态方法只是一个独立的函数,恰巧放在了类里,他跟这个类有关系(逻辑上的关系,比如是为此类服务的,但无实质的交互),与类中的其他方法或属性无交互。这里边传递了一个类属性250
    
        @staticmethod
        def get_date_static(data_as_string):  # 不能传递和类或实例相关的参数,如cls或self,但可以传递其他参数
            year,month,day=map(int,data_as_string.split('-'))
            return Data_test(year,month,day)
    
        def out_date(self):  # 最常见的实例方法
            print "year :"
            print self.year
            print "month :"
            print self.month
            print "day :"
            print self.day
    
    # 类方法和静态方法调用方式一致,类名.方法名(参数),注意类名后边没有() 
    # 如果有括号相当于i=Data_test()实例化之后,再调用类方法i.get_date_class(),这样就多创建了一个对象i,虽然结果一致,但意义不同了。
    # 另外再多说一句,如果i=Data_test(),之后直接去调用i()(对象名+括号),会自动调用类中的def __call__(self):方法,如果没定义就会报错,这里扯远了,和本文无关
    c=Data_test.get_date_class("2015-5-5")
    c.out_date()
    s=Data_test.get_date_static("2016-6-6")
    s.out_date()
    
    
  • 看下结果

    year :
    2015
    month :
    5
    day :
    250  # 这里被cls.forclass覆盖了
    year :
    2016
    month :
    6
    day :
    6
    
  • 这里可能有个疑问,如果不用静态方法或者类方法,如何实现上边的功能呢。

    
    # 如果不用类方法或者静态方法呢,还想支持2015-5-5的时间格式,怎么办呢
    # 方法1:在类外边定义一个函数,然后先通过此函数处理,将处理的结果传入类的参数里,这肯定不是好的方法,本身get_date_instance只为Data_test服务的,但现在却又脱离在他之外了。  
    def get_date_instance(data_as_string):
        year,month,day=map(int,data_as_string.split('-'))
        result = {}
        result['year'] = year
        result['month'] = month
        result['day'] = day
        return result
    # 调用
    i=Data_test(**get_date_instance("2016-6-6"))
    i.out_date()
    
    # 方法2:重新定义类的__init__方法,对传入的值进行判断,如果为2016-6-6这种格式,对他进行格式化,相当于把get_date_instance函数的内容放到__init__里了,这样的坏处就是不灵活,如果重构get_date_instance的逻辑,需要动__init__,不便于维护    
    
    

参考资料

http://stackoverflow.com/questions/12179271/python-classmethod-and-staticmethod-for-beginner/12179325#12179325
http://blog.csdn.net/a447685024/article/details/52424481

posted @ 2016-11-01 20:06  三流码农  阅读(710)  评论(0编辑  收藏  举报