• Python的静态方法和类成员方法 分类: python基础学习 2014-08-13 14:21 205人阅读 评论(0) 收藏


    http://www.cnblogs.com/2gua/archive/2012/09/03/2668125.html

    Python的静态方法和类成员方法都可以被类或实例访问,两者概念不容易理清,但还是有区别的:
    1)静态方法无需传入self参数,类成员方法需传入代表本类的cls参数;(参数cls代表本类)
    2)从第1条,静态方法是无法访问实例变量的,而类成员方法也同样无法访问实例变量,但可以访问类变量
    3)静态方法有点像函数工具库的作用,而类成员方法则更接近类似Java面向对象概念中的静态方法。
     
    实现静态方法和类方法的两种方式
    一、在Python 2.3及之前,用staticmethod和classmethod类型对象包装实现
    例子如下(注意print里的说明):
    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.smd()
    >>> mc.cmd()
    >>> MyClass.smd()
    >>> MyClass.cmd()
     
    二、在Python 2.4及之后,用装饰器(decorators)实现
    装饰器使用@操作符,例子如下:
    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.staticmd()  # 实例调用静态方法,无法访问实例变量val1和val2
    >>> 
    静态方法,无法访问val1和val2
     
    >>> mc.classmd()  # 实例调用类方法,注意,这里访问的是类MyClass的变量val1的值,不是实例化后mc的实例变量val1,这里容易混淆,往下看就会明白。val2一直是实例变量,所以无法访问
    >>> 
    类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值

    >>> MyClass.staticmd()  # 类直接调用静态方法,结果同上面的实例调用,无论是类变量还是实例变量都无法访问
    >>> 
    静态方法,无法访问val1和val2
     
    >>> MyClass.classmd()  # 类直接调用类方法,结果同上面的实例调用
    >>> 
    类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值
     
    >>> mc.val1 = 'Value changed'  # 改变实例变量val1的值

    >>> mc.classmd()  # 实例调用类方法,注意到cls.val1的值没变,所以,这时的cls.val1是类变量val1,而非实例变量val1
    >>> 
    类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值

    >>> MyClass.classmd()  # 类直接调用类方法,结果同上面的实例调用
    >>> 
    类方法,类:__main__.MyClass,val1:Value 1,无法访问val2的值
     
    >>> MyClass.val1 = 'Class Value changed'  # 改变类变量val1的值

    >>> mc.classmd()  # 实例调用类方法,注意到cls.val1的值变了,所以,进一步证明了这时的cls.val1是类变量val1,而非实例变量val1
    >>> 
    类方法,类:__main__.MyClass,val1:Class Value changed,无法访问val2的值
     
    >>> MyClass.classmd()  # 类直接调用类方法,结果同上面的实例调用
    >>> 
    类方法,类:__main__.MyClass,val1:Class Value changed,无法访问val2的值
     
    结论
    如果上述执行过程太复杂,记住以下两点就好了:
    静态方法:无法访问类属性、实例属性,相当于一个相对独立的方法,跟类其实没什么关系,换个角度来讲,其实就是放在一个类的作用域里的函数而已。
    类成员方法:可以访问类属性,无法访问实例属性。上述的变量val1,在类里是类变量,在实例中又是实例变量,所以容易混淆。

  • 相关阅读:
    winform 监视DataGridView的滚动条,加载数据
    SQL 自动生成行号
    SQL 删除重复的数据(多个字段判断),只保留一条数据
    C# 一个简单的 工厂模式 例子
    winform 重写TextBox的OnTextChanged方法(事件)
    winform 给文本框加载内容的时候 始终让文本框的滚动条到底(允许显示多行Multiline=True)
    winform 制定DataGridViewTextColumn列(更改DataGridView的Cell的状态很有用)
    winform 使用委托 实现多线程访问控件
    C# 一个简单的递归函数和 两个List<T> 合并
    ADO.NET  把数据库A的某表的数据内容复制到数据库B的某表内
  • 原文地址:https://www.cnblogs.com/think1988/p/4627909.html
Copyright © 2020-2023  润新知