Python OOP(2)-static method,class method and instance method

 

静态方法(Static Method)

一种简单函数,符合以下要求:

1.嵌套在类中。

2.没有self参数。

特点

1.类调用、实例调用,静态方法都不会接受自动的self参数。

2.会记录所有实例的信息,而不是为实例提供行为。

 简单说staticmethod 无法访问类属性、实例属性,相当于一个相对独立的方法,跟类其实没什么关系,换个角度来讲,其实就是放在一个类的作用域里的函数而已。

 

#!python2
#-*- coding:utf-8 -*-

class A:
    v1="class argu"
    
    def __init__(self):
        self.v1="instance argu"
        
    def fun1():
        print "Static fun"
        
    fun1=staticmethod(fun1)
    

a=A()

#实例调用
a.v1

'instance argu'

#类调用
A.v1

'class argu'

a.fun1()
            
A.fun1()

 

另一种写法是在python2.4以后用装饰器decorator

#!python2
#-*- coding:utf-8 -*-

class A:
    v1="class argu"
    
    def __init__(self):
        self.v1="instance argu"
     
    @staticmethod   
    
    def fun1():
        print "Static fun"
        
    

a=A()

#实例调用
a.v1

'instance argu'

#类调用
A.v1

'class argu'

a.fun1()
            
A.fun1()

 

类方法(Class Method)

一种函数,符合以下特征

1.类调用、或实例调用,传递的参数是一个类对象。

注意classmethod 可以访问类属性,无法访问实例属性。上述的变量val1,在类里是类变量,在实例中又是实例变量,所以容易混淆

适用于:

 

程序需要处理与类而不是与实例相关的数据。也就是说这种数据信息通常存储在类自身上,不需要任何实例也可以处理。

 

例如:

 

1.记录有一个类创建的实例的数目。

 

2.维护当前内存中一个类的所有实例的列表。

 

以上情况也可以同以下方式解决:

 

在类定义之外生成一个的简单函数

 

 

#记录实例创建数目

def amountinstance():
    print "Amount of instances is : %d" %(c1.numInstance)
    
    
class c1:
    numInstance=0
    def __init__(self):
        c1.numInstance+=1
        

a=c1()
b=c1()
c=c1()
amountinstance()

3

 

因为类名称对简单函数而言,是可读取的全局变量,所以看到上例可以正常工作。

此外,函数名变成了全局变量,故仅适用于这个单一模块。

这样处理的缺点如下:

1.给文件的作用域添加了一个额外的名称,该名称仅能处理单个的类,不能应付多个类需要处理的情况。

2.该函数与类的直接关联很小,函数的定义可能在数百行代码之外的位置。

3.该函数位于类的命名空间之外,子类不能通过重新定义来代替或扩展它。

 

 

 

 

 

class MyClass:
    val1 = 'Value 1'
    def __init__(self):
        self.val2 = 'Value 2'
    def staticmd():
        print '静态方法,无法访问val1和val2'
    smd = staticmethod(staticmd)

    def classmd(cls):
        print '类方法,类:' + str(cls) + ',val1:' + cls.val1 + ',无法访问val2的值'
    cmd = classmethod(classmd)
    
    
    
    
mc = MyClass()
mc.cmd()

类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值

MyClass.cmd()

类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值

 

另一种写法是在python2.4以后用装饰器decorator

class MyClass:
    val1 = 'Value 1'
    def __init__(self):
        self.val2 = 'Value 2'
        
    @staticmethod
        
    def staticmd():
        print '静态方法,无法访问val1和val2'
    
    @classmethod
    
    def classmd(cls):
        print '类方法,类:' + str(cls) + ',val1:' + cls.val1 + ',无法访问val2的值'

    
    
    
    
mc = MyClass()
mc.classmd()

类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值

MyClass.classmd()

类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值


#实例的val1与类的val1是不一样的,类方法可以访问的是类的val1

mc.val1 = 'Value changed'
mc.classmd()
类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值

MyClass.classmd()
类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值

MyClass.val1='Value changed'
mc.classmd()

类方法,类:__main__.MyClass,val1:Value changed,无法访问val2的值

MyClass.classmd()

类方法,类:__main__.MyClass,val1:Value changed,无法访问val2的值

 

最后汇总instance method, static method 和class method 的实现和调用

 

#!python2
#-*- coding:utf-8 -*-

class Methods():
    
    
    def im(self,v2):
        self.v2=v2
        print "Call instance method: %d " % v2
        
    @staticmethod
    
    def sm(v2):
        print "Call static method: %d " % v2
        
    @classmethod
    
    def cm(cls,v2):
        print "Call class method: %d " % v2
        

obj=Methods()
    
#instance method call 
#实例方法调用一定要将类实例化,方可通过实例调用

obj.im(1)

Call instance method: 1 


Methods.im(obj,1)

Call instance method: 1 


#static method call
#静态方法调用时不需要实例参数
obj.sm(2)

Call static method: 2 

Methods.sm(2)

Call static method: 2 

#class method call
# 类方法调用时,Python会把类(不是实例)传入类方法第一个(最左侧)参数cls(默认)

obj.cm(3)

Call class method: 3 

Methods.cm(3)

Call class method: 3 

 

posted on 2017-02-17 14:14  大大的橙子  阅读(330)  评论(0编辑  收藏  举报

导航