Python 实例方法_类方法_静态方法

实例方法  类方法   静态方法

 

类实例方法:第一个参数强制为类实例对象,可以通过这个类实例对象访问类属性,可以通过类实例对象的__class__属性访问类属性。

类方法:第一个参数强制为类对象,可以通过这个类对象访问类属性,由于没有传入类实例对象,所以不能访问类实例属性

类静态方法:无法访问类属性、类实例属性、没有默认的第一个参数,其实跟类没什么关系,只是绑定在类命名空间下的函数而已

类静态方法通常用来定义一些和类主题相关的函数

 

通过类对象可以调用类方法、类静态方法,但不可以调用类实例方法;通过类实例对象可以调用以上三种方法

 

 

 

静态方法是指类中无需实例参与即可调用的方法(不需要self参数),在调用过程中,无需将类实例化,直接在类之后使用.号运算符调用方法。

 

通常情况下,静态方法使用@staticmethod装饰器来声明。

# -*- coding: utf-8 -*-
class dog:
    @staticmethod
    def d():
        print '我是静态方法'
    def e(self):
        print '我是实例方法'
dog.d()
#dog.e()    TypeError: unbound method e() must be called with dog instance as first argument (got nothing instead)
a=dog()
a.d()
a.e()

 

而在Python 3中,如果一个类的方法不需要self参数,不再需要声明为静态方法,但是这样的话只能通过类去调用这个方法,如果使用实例调用这个方法会引发异常。

# -*- coding: utf-8 -*-
class dog():
    @staticmethod
    def a():
        print('我是静态方法')
    def b():
        print('我是静态方法,没有self参数,不能实例调用')
dog.a()
dog.b()
d=dog()
d.a()
#d.b()      TypeError: b() takes 0 positional arguments but 1 was given

  

 

类方法内部没有self属性,有cls属性

python2 静态方法不需要必须加上@staticmethod装饰器,

class dog:
    @classmethod
    def d(cls):
        print type(cls)
    def e(self):
        print type(self)
dog.d()                        #<type 'classobj'>    类方法可以不需实例化直接调用,必须传入cls参数,在类方法调用时候cls代表类
a=dog()
a.e()                          #<type 'instance'>    实例方法的实例化调用,self代表dog类
a.d()                          #<type 'classobj'>    类方法可以实例调用
#dog.e()                   #TypeError: unbound method e() must be called with dog instance as first argument (got nothing instead)
#实例方法必须先实例化,实例调用

  

 

 

>>> #-*- coding:utf-8 -*-
... class A(object):      #实例方法和类方法中的self和cls这两个字符本身没有什么特殊,完全可以用别的字符如hello或者hi来代替,但是python中约定俗成默认用self和cls来作为实例方法和类方法的第一个参数
...     a = 1          #在调用方法时,self用来指代实例对象,cls用来指代类对象本身;静态方法因为本身与类中其他变量或者方法没有关联,所以不需要这样一个参数;
...     def instance_method(self):              #实例方法instance_method()的定义不需要声明,默认需要一个self参数作为第一个参数,在调用的时候这个self参数指代实例对象
...             print '实例方法打印类变量a: %s' % self.a      
...     @classmethod                      #类方法class_method()需要用装饰器@classmethod来声明
...     def class_method(cls):                #默认需要一个cls参数作为函数的第一个参数,在调用的时候这个cls参数指代类对象,这样定义的好处是不需要实例化类对象即可调用这个方法
...             print '类方法打印类变量a: %s' % cls.a
...     @staticmethod                     #静态方法static_method()需要用装饰器@staticmethod来声明
...     def static_method(b):                #其实静态变量就是在类中定义的跟这个类没有关系的方法,它不引用类的变量,也跟类中的其他函数没有关联,完全自己玩自己的
...             print '静态方法打印自己的变量b: %s' % b   #但是既然定义在类中,就得通过类对象或者实例对象来调用
...
>>> A.instance_method()          #实例方法不能直接访问(不能为类对象访问)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method instance_method() must be called with A instance as first argument (got nothing instead)
>>>
>>> A().instance_method()         #A()是实例对象 (可以用实例对象A().instance_method()调用 )        
实例方法打印类变量a: 1
>>>
>>> A.class_method()            #类方法传入的cls代表类对象, 这样不需要实例化类对象即可调用这个方法
类方法打印类变量a: 1
>>>
>>> A().class_method()           #类方法也可以通过实例对象调用:A().class_method();
类方法打印类变量a: 1
>>>
>>> A.static_method(12)          #静态方法 不用实例化 直接访问
静态方法打印自己的变量b: 12
>>>
>>> A().static_method(12)         #静态方法 从 类访问
静态方法打印自己的变量b: 12

 

静态方法

class Date:
    def __init__(self,year,month,day):
        self.year=year
        self.month=month
        self.day=day
    @staticmethod
    def now(): #用Date.now()的形式去产生实例,该实例用的是当前时间
        t=time.localtime() #获取结构化的时间格式
        return Date(t.tm_year,t.tm_mon,t.tm_mday) #新建实例并且返回
    @staticmethod
    def tomorrow():#用Date.tomorrow()的形式去产生实例,该实例用的是明天的时间
        t=time.localtime(time.time()+86400)
        return Date(t.tm_year,t.tm_mon,t.tm_mday)

a=Date('1987',11,27) #自己定义时间
b=Date.now() #采用当前时间
c=Date.tomorrow() #采用明天的时间

print(a.year,a.month,a.day)
print(b.year,b.month,b.day)
print(c.year,c.month,c.day)

 

类方法

class A:
    x=1
    @classmethod
    def test(cls):
        print(cls)      
        print(cls.x)    

class B(A):
    x=2
B.test()

'''
#输出 <class '__main__.B'> 2
#输出 2
'''

 

import time
class Date:
    def __init__(self,year,month,day):
        self.year=year
        self.month=month
        self.day=day
    @staticmethod
    def now():                #静态方法没有cls传入,只属于自身类,继承时候不能直接访问
        t=time.localtime()
        return Date(t.tm_year,t.tm_mon,t.tm_mday)

class EuroDate(Date):
    def __str__(self):
        return 'year:%s month:%s day:%s' %(self.year,self.month,self.day)

e=EuroDate.now()
print(e) #我们的意图是想触发EuroDate.__str__,但是结果为
'''
输出结果:
<__main__.Date object at 0x1013f9d68>
'''

  

import time
class Date:
    def __init__(self,year,month,day):
        self.year=year
        self.month=month
        self.day=day
    # @staticmethod
    # def now():
    #     t=time.localtime()
    #     return Date(t.tm_year,t.tm_mon,t.tm_mday)

    @classmethod #改成类方法
    def now(cls):                   #类方法的cls关联了对应实例EuroDate
        t=time.localtime()
        return cls(t.tm_year,t.tm_mon,t.tm_mday) #哪个类来调用,即用哪个类cls来实例化

class EuroDate(Date):
    def __str__(self):
        return 'year:%s month:%s day:%s' %(self.year,self.month,self.day)

e=EuroDate.now()
print(e) #我们的意图是想触发EuroDate.__str__,此时e就是由EuroDate产生的,所以会如我们所愿
'''
输出结果:
year:2017 month:3 day:3
'''

 

posted @ 2019-04-03 21:50  skyfly0772  阅读(191)  评论(0编辑  收藏  举报