python中的实例方法、静态方法、类方法、类变量和实例变量浅析


Posted in Python onApril 26, 2014

注:使用的是Python2.7。

一、实例方法

实例方法就是类的实例能够使用的方法。如下:

class Foo:
    def __init__(self, name):
        self.name = name
    def hi(self):
        print self.name
if __name__ == '__main__':
    foo01 = Foo('letian')
    foo01.hi()
    print type(Foo)
    print type(foo01)
    print id(foo01)
    print id(Foo)

运行结果为:
letian
<type 'classobj'>
<type 'instance'>
40124704
31323448[code]
可以看到,Foo的type为classobj(类对象,python中定义的类本身也是对象),foo01的type为instance(实例)。而hi()是实例方法,所以foo01.hi()会输出'letian'。实例方法的第一个参数默认为self,代指实例。self不是一个关键字,而是约定的写法。init()是生成实例时默认调用的实例方法。将Foo的定义改为以下形式:
[code]class Foo:
    def __init__(this, name):
        this.name = name
    def hi(here):
        print here.name

运行依然正确。 内置函数id用来查看对象的标识符,下面是其doc内容:
>>> print id.__doc__
id(object) -> integer
Return the identity of an object.  This is guaranteed to be unique among
simultaneously existing objects.  (Hint: it's the object's memory address.)

二、静态方法

静态方法是一种普通函数,就位于类定义的命名空间中,它不会对任何实例类型进行操作。使用装饰器@staticmethod定义静态方法。类对象和实例都可以调用静态方法:

class Foo:
    def __init__(self, name):
        self.name = name
    def hi(self):
        print self.name
    @staticmethod
    def add(a, b):
        print a + b
if __name__ == '__main__':
    foo01 = Foo('letian')
    foo01.hi()
    foo01.add(1,2)
    Foo.add(1, 2)

    运行结果如下:

letian
3
3

注意,很多编程语言不允许实例调用静态方法。

三、类方法

类方法是将类本身作为对象进行操作的方法。类方法使用@classmethod装饰器定义,其第一个参数是类,约定写为cls。类对象和实例都可以调用类方法:

class Foo:
    name = 'letian '
    @classmethod
    def hi(cls, x):
        print cls.name * x
if __name__ == '__main__':
    foo01 = Foo()
    foo01.hi(2)
    Foo.hi(3)

运行结果如下:
letian letian 
letian letian letian

注意,很多其他的编程语言不允许实例调用类方法。

四、super

super用来执行父类中的函数,例如:

class Foo(object):
    def hi(self):
        print 'hi,Foo'
class Foo2(Foo):
    def hi(self):
        super(Foo2, self).hi()
if __name__ == '__main__':
    foo2 = Foo2()
    foo2.hi()

运行结果:
hi,Foo

注意,Foo类必须继承某个类(并且这个继承链开始于object类),否则会报错。如果改成下面的形式:
class Foo:
    def hi(self):
        print 'hi,Foo'
class Foo2(Foo):
    def hi(self):
        super(Foo2, self).hi()
if __name__ == '__main__':
    foo2 = Foo2()
    foo2.hi()

运行时报错如下:
......
TypeError: must be type, not classobj

关于super,具体请见http://docs.python.org/2/library/functions.html?highlight=super#super以及super.doc。

五、类变量和实例变量

类变量定义在类的定义之后,实例变量则是以为self.开头。例如:

class Foo(object):
    val = 0
    def __init__(self):
        self.val = 1
if __name__ == '__main__':
    foo = Foo()
    print foo.val
    print Foo.val

运行结果为:
1
0

实例也能够访问类变量,如下:
class Foo(object):
    val = 0
    def __init__(self):
        pass
if __name__ == '__main__':
    foo = Foo()
    print foo.val
    print Foo.val

运行结果如下:
0
0

另外,可以通过以下方式访问类变量:
class Foo(object):
    val = 3
    def __init__(self):
        print self.__class__.val
if __name__ == '__main__':
    foo = Foo()

运行结果:
3

还可以这样:
class Foo(object):
    val = 3
    def __init__(self):
        pass
    @classmethod
    def echo(cls):
        print cls.val
if __name__ == '__main__':
    Foo.echo()

运行结果:
3

六、如何调用父类的构造函数

子类(派生类)并不会自动调用父类(基类)的init方法,例如:

class Foo(object):
    def __init__(self):
        self.val = 1
class Foo2(Foo):
    def __init__(self):
        print self.val
if __name__ == '__main__':
    foo2 = Foo2()

运行时报错。

调用父类的init方法有两种,第一种:

class Foo(object):
    def __init__(self):
        self.val = 1
class Foo2(Foo):
    def __init__(self):
        Foo.__init__(self)
        print self.val
if __name__ == '__main__':
    foo2 = Foo2()

第二种:
class Foo(object):
    def __init__(self):
        self.val = 1
class Foo2(Foo):
    def __init__(self):
        super(Foo2,self).__init__()
        print self.val
if __name__ == '__main__':
    foo2 = Foo2()

这两种方法的运行结果均为:
1

不过这两种方法是有区别的。
Python 相关文章推荐
python求列表交集的方法汇总
Nov 10 Python
Python脚本简单实现打开默认浏览器登录人人和打开QQ的方法
Apr 12 Python
Python 中 list 的各项操作技巧
Apr 13 Python
python中requests库session对象的妙用详解
Oct 30 Python
python中pip的安装与使用教程
Aug 10 Python
pymysql 开启调试模式的实现
Sep 24 Python
Python使用tkinter模块实现推箱子游戏
Oct 08 Python
django使用xadmin的全局配置详解
Nov 15 Python
TensorFlow dataset.shuffle、batch、repeat的使用详解
Jan 21 Python
Python 测试框架unittest和pytest的优劣
Sep 26 Python
python 邮件检测工具mmpi的使用
Jan 04 Python
Jupyter Notebook添加代码自动补全功能的实现
Jan 07 Python
Python设计模式之单例模式实例
Apr 26 #Python
Python设计模式之观察者模式实例
Apr 26 #Python
Python设计模式之代理模式实例
Apr 26 #Python
python中的列表推导浅析
Apr 26 #Python
Python中的Numpy入门教程
Apr 26 #Python
Python中的map、reduce和filter浅析
Apr 26 #Python
Python实现的Kmeans++算法实例
Apr 26 #Python
You might like
谷歌音乐搜索栏的提示功能php修正代码
2011/05/09 PHP
Symfony2学习笔记之控制器用法详解
2016/03/17 PHP
PHP空值检测函数与方法汇总
2017/11/19 PHP
PHP简单实现欧拉函数Euler功能示例
2017/11/06 PHP
php实现微信企业付款到个人零钱功能
2018/10/09 PHP
为什么要在引入的css或者js文件后面加参数的详细讲解
2013/05/03 Javascript
url参数中有+、空格、=、%、&amp;、#等特殊符号的问题解决
2013/05/15 Javascript
jquery中EasyUI使用技巧小结
2015/02/10 Javascript
JavaScript的9种继承实现方式归纳
2015/05/18 Javascript
JavaScript获取tr td 的三种方式全面总结(推荐)
2017/08/15 Javascript
js中bool值的转换及“&amp;&amp;”、“||”、 “!!”详解
2017/12/21 Javascript
js正则相关知识点专题
2018/05/10 Javascript
vue2中引用及使用 better-scroll的方法详解
2018/11/15 Javascript
ES6 Object方法扩展的应用实例分析
2019/06/25 Javascript
[06:10]6.81新信使新套装!给你一个炫酷的DOTA2
2014/05/06 DOTA
python批量导出导入MySQL用户的方法
2013/11/15 Python
python实现的登陆Discuz!论坛通用代码分享
2014/07/11 Python
Python编程把二叉树打印成多行代码
2018/01/04 Python
Django框架中序列化和反序列化的例子
2019/08/06 Python
详解python中__name__的意义以及作用
2019/08/07 Python
Python3使用PySynth制作音乐的方法
2019/09/09 Python
使用PyTorch实现MNIST手写体识别代码
2020/01/18 Python
快速查找Python安装路径方法
2020/02/06 Python
Python如何读写字节数据
2020/08/05 Python
如何使用PyCharm引入需要使用的包的方法
2020/09/22 Python
python 制作磁力搜索工具
2021/03/04 Python
推荐WEB开发者最佳HTML5和CSS3代码生成器
2015/11/24 HTML / CSS
4s店总经理岗位职责
2013/12/31 职场文书
大学英语演讲稿(中英文对照)
2014/01/14 职场文书
中医学专业自荐信范文
2014/04/01 职场文书
综艺节目策划方案
2014/06/13 职场文书
Redis 配置文件重要属性的具体使用
2021/05/20 Redis
Python爬虫基础初探selenium
2021/05/31 Python
详细了解MVC+proxy
2021/07/09 Java/Android
Django + Taro 前后端分离项目实现企业微信登录功能
2022/04/07 Python
Django框架中表单的用法
2022/06/10 Python