zoukankan      html  css  js  c++  java
  • 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 
  • 相关阅读:
    教你如何自定义组件
    android应用开发小技巧
    改变Vim在iTerm2中的光标
    Mac添加bash alias
    tmux常用命令
    javascript Date 总结
    ES6箭头函数
    npm常用命令
    ES6 import export
    gitingore
  • 原文地址:https://www.cnblogs.com/dadadechengzi/p/6409637.html
Copyright © 2011-2022 走看看