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 实现红包随机生成算法的简单实例
Jan 04 Python
NetworkX之Prim算法(实例讲解)
Dec 22 Python
python调用xlsxwriter创建xlsx的方法
May 03 Python
使用Django启动命令行及执行脚本的方法
May 29 Python
Python日期时间Time模块实例详解
Apr 15 Python
python在新的图片窗口显示图片(图像)的方法
Jul 11 Python
对python while循环和双重循环的实例详解
Aug 23 Python
python getpass模块用法及实例详解
Oct 07 Python
用Python在Excel里画出蒙娜丽莎的方法示例
Apr 28 Python
python实现文法左递归的消除方法
May 22 Python
Python 串口通信的实现
Sep 29 Python
关于 Python json中load和loads区别
Nov 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
如何解决CI框架的Disallowed Key Characters错误提示
2013/07/05 PHP
php计算当前程序执行时间示例
2014/04/24 PHP
destoon数据库表说明汇总
2014/07/15 PHP
php+MySQL判断update语句是否执行成功的方法
2014/08/28 PHP
Yii配置与使用memcached缓存的方法
2016/07/13 PHP
PHP面向对象程序设计OOP继承用法入门示例
2016/12/27 PHP
javascript Xml增删改查(IE下)操作实现代码
2009/01/30 Javascript
层序遍历在ExtJs的TreePanel中的应用
2009/10/16 Javascript
25个优雅的jQuery Tooltip插件推荐
2011/05/25 Javascript
JS图片预加载 JS实现图片预加载应用
2012/12/03 Javascript
jquery制作弹窗提示窗口代码分享
2014/03/02 Javascript
基于ajax实现文件上传并显示进度条
2015/08/03 Javascript
js时间戳格式化成日期格式的多种方法介绍
2017/02/16 Javascript
微信小程序后台解密用户数据实例详解
2017/06/28 Javascript
angular $watch 一个变量的变化(实例讲解)
2017/08/02 Javascript
vue插件draggable实现拖拽移动图片顺序
2018/12/01 Javascript
Vue 中文本内容超出规定行数后展开收起的处理的实现方法
2019/04/28 Javascript
vue实现拖拽效果
2019/12/23 Javascript
基于JavaScript获取url参数2种方法
2020/04/17 Javascript
如何利用nodejs实现命令行游戏
2020/11/24 NodeJs
使用python BeautifulSoup库抓取58手机维修信息
2013/11/21 Python
Python编写一个闹钟功能
2017/07/11 Python
python3利用Dlib19.7实现人脸68个特征点标定
2018/02/26 Python
python使用mysql的两种使用方式
2018/03/07 Python
Python之列表的插入&amp;替换修改方法
2018/06/28 Python
python pygame模块编写飞机大战
2018/11/20 Python
Python 实现子类获取父类的类成员方法
2019/01/11 Python
python连接PostgreSQL过程解析
2020/02/09 Python
New Balance澳大利亚官网:运动鞋和健身服装
2019/02/23 全球购物
意大利时尚奢侈品店:D’Aniello Boutique
2021/01/19 全球购物
事业单位分类改革实施方案
2014/03/21 职场文书
公司员工活动策划方案
2014/08/20 职场文书
2015年除四害工作总结
2015/07/23 职场文书
2016党员干部反腐倡廉心得体会
2016/01/13 职场文书
听课评课活动心得体会
2016/01/15 职场文书
python使用pygame创建精灵Sprite
2021/04/06 Python