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的框架中为MySQL实现restful接口的教程
Apr 08 Python
Python的自动化部署模块Fabric的安装及使用指南
Jan 19 Python
12步教你理解Python装饰器
Feb 25 Python
Python配置mysql的教程(推荐)
Oct 13 Python
Python向MySQL批量插数据的实例讲解
Mar 31 Python
利用Pandas 创建空的DataFrame方法
Apr 08 Python
浅谈pandas用groupby后对层级索引levels的处理方法
Nov 06 Python
python pyheatmap包绘制热力图
Nov 09 Python
Scrapy框架爬取西刺代理网免费高匿代理的实现代码
Feb 22 Python
Python3实现计算两个数组的交集算法示例
Apr 03 Python
详解python编译器和解释器的区别
Jun 24 Python
Python过滤掉numpy.array中非nan数据实例
Jun 08 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
用文本文件制作留言板提示(上)
2006/10/09 PHP
PHP多进程编程实例
2014/10/15 PHP
Json_decode 解析json字符串为NULL的解决方法(必看)
2017/02/17 PHP
In Javascript Class, how to call the prototype method.(three method)
2007/01/09 Javascript
仿服务器端脚本方式的JS模板实现方法
2007/04/27 Javascript
js中的异常处理try...catch使用介绍
2013/09/21 Javascript
jQuery源码解读之removeAttr()方法分析
2015/02/20 Javascript
js简单倒计时实现代码
2016/04/30 Javascript
jQuery 调用WebService 实例讲解
2016/06/28 Javascript
js实现百度搜索提示框
2017/02/05 Javascript
对称加密与非对称加密优缺点详解
2017/02/06 Javascript
在 Angular 中实现搜索关键字高亮示例
2017/03/21 Javascript
JS解析url查询参数的简单代码
2017/08/06 Javascript
JavaScript模块详解
2017/12/18 Javascript
详解微信小程序调起键盘性能优化
2018/07/24 Javascript
Node.js系列之连接DB的方法(3)
2019/08/30 Javascript
JavaScript基于SVG的图片切换效果实例代码
2020/12/15 Javascript
[09:59]DOTA2-DPC中国联赛2月7日Recap集锦
2021/03/11 DOTA
py中的目录与文件判别代码
2008/07/16 Python
在python中利用GDAL对tif文件进行读写的方法
2018/11/29 Python
Python hashlib模块加密过程解析
2019/11/05 Python
Python递归调用实现数字累加的代码
2020/02/25 Python
Python读取图像并显示灰度图的实现
2020/12/01 Python
纯CSS3打造动感漂亮时尚的扇形菜单
2014/03/18 HTML / CSS
西班牙宠物用品和食品网上商店:Tiendanimal
2019/06/06 全球购物
DELPHI面试题研发笔试试卷
2015/11/08 面试题
保荐人的岗位职责
2013/11/19 职场文书
学校联谊活动方案
2014/02/15 职场文书
加强机关作风建设心得体会
2014/10/22 职场文书
办公室主任岗位职责
2015/01/31 职场文书
课外活动总结
2015/02/04 职场文书
小学数学教师研修日志
2015/11/13 职场文书
读《皮囊》有感:理解是对他人的最大的善举
2019/11/14 职场文书
Java Dubbo框架知识点梳理
2021/06/26 Java/Android
JavaScript实例 ODO List分析
2022/01/22 Javascript
CSS3实现360度循环旋转功能
2022/02/12 HTML / CSS