Python的静态方法和类成员方法都可以被类或实例访问,两者概念不容易理清,但还是有区别的:
1)静态方法无需传入self参数,类成员方法需传入代表本类的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的值
 
结论
如果上述执行过程太复杂,记住以下两点就好了:
 

1. 静态成员方法: 不能访问类属性,实例属性,相当于一个独立的方法,可以理解和类没关系,只是用类加了个作用域,比如:一个类,有三种加密算法,可以考虑静态方法;
2. 类成员方法   : 能访问类属性,无法访问实例属性,这里要注意,python是动态语言,和c++不同,实例是可以动态添加属性的,即实例的属性和类的属性不一定一样

 

python中的静态成员方法和类成员方法的更多相关文章

  1. 关于如何在Python中使用静态、类或抽象方法的权威指南

    Python中方法的工作方式 方法是存储在类属性中的函数,你可以用下面这种方式声明和访问一个函数 >>> class Pizza(object): ... def __init__( ...

  2. python中的单例模式、元类

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...

  3. python中重要的概念:类(class)

    1.名词解释 类:类代表了具有相同特征的一类事物(人) 对象.实例:具体的某一个事物或者是人 实例化:将类变成对象的这么一个过程,即新建一个对象的过程,就是对类的一个实例化过程. 2.格式 函数定义: ...

  4. python中的实例属性和类属性

    在python中,类属性和实例属性的区别是什么? 我认为是作用域的不同,实例对象可以访问类属性,类对象不可以访问实例属性.(类的概念本身就是作用域的概念,你不能让一只猫会飞,猫属于猫类,这一类都不会飞 ...

  5. python中的面向对象学习以及类的封装(这篇文章初学者一定要好好看)

    这篇文章对于初学者可以很有效的理解面对过程.面对对象 一.首先介绍一下面向过程和面向对象的比较: 面向过程 VS 面向对象 编程范式 编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何 ...

  6. python中的面向对象学习以及类的多态

    接下来类的第三个重要的特性:多态(一种接口,多种实现) 多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特 ...

  7. PyCharm使用正则替换python中的静态资源

    python每次开发前台页面时,最无法避免的就是前台静态资源地址的替换了,手动替换成{% static 'web/.......' %}可想而知的痛苦,把正则替换的方式分享给朋友们,希望可以帮助到需要 ...

  8. python小知识-__call__和类装饰器的结合使用,数据描述符__get__\__set__\__delete__(描述符类是Python中一种用于储存类属性值的对象)

    class Decorator(): def __init__(self, f): print('run in init......') self.f = f def __call__(self, a ...

  9. python中的面向对象学习以及类的继承和继承顺序

    继承 首先编写一串关于类的代码行: __author__ = "Yanfeixu" # class People: 经典类不用加(object) class People(obje ...

随机推荐

  1. GIT(1)----更新代码和上传代码操作的步骤

    1.第一次下载代码 a.首先获得下载的地址,可从服务器,或者GitHut上获得.例如http://100.211.1.110:21/test/test.git b.终端里切换到想要将代码存放的目录,在 ...

  2. ROWID面试题-删除表中重复数据(重复数据保留一个)

    /* ROWID是行ID,通过它一定可以定位到r任意一行的数据记录 ROWID DNAME DEPTNO LOC ------------------ ------------------------ ...

  3. Android 性能监控系列一(原理篇)

    欢迎关注微信公众号:BaronTalk,获取更多精彩好文! 一. 前言 性能问题是导致 App 用户流失的罪魁祸首之一,如果用户在使用我们 App 的时候遇到诸如页面卡顿.响应速度慢.发热严重.流量电 ...

  4. Java_基础知识回顾

    1.ByteArrayInputStream. ByteArrayOutputStream String str = "ZHANGSAN"; //System.out.printl ...

  5. 忘记Oracle系统管理员sys的密码

    sqlplus / as sysdba; alter user sys identified by newpwd***;

  6. UVa11187

    莫勒定理,证明如下: 请结合下图看代码: #include <iostream> #include <math.h> #include <iomanip> usin ...

  7. 实效云计算用户组(ECUG) 与 阿里云

    http://www.ecug.org/ http://www.aliyun.com/   阿里云

  8. 配置使用ldap中碰到的各种问题 --- 吐血

    1.   LDAP Result Code 50 "Insufficient Access Rights" : 权限的问题: 解决: 使用docker部署吧, 看我其他的博客

  9. Asp.Net Core App 部署故障示例 2

    相关阅读:Windows + IIS 环境部署Asp.Net Core App 1.  HTTP Error 502.5 – Process Failure 环境 Windows Server 201 ...

  10. kafka存储机制

    kafka存储机制 @(博客文章)[storm|大数据] kafka存储机制 一关键术语 二topic中partition存储分布 三 partiton中文件存储方式 四 partiton中segme ...