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 相关文章推荐
numpy数组拼接简单示例
Dec 15 Python
wxPython的安装图文教程(Windows)
Dec 28 Python
Python测试人员需要掌握的知识
Feb 08 Python
python爬虫获取多页天涯帖子
Feb 23 Python
Python 给某个文件名添加时间戳的方法
Oct 16 Python
使用Python进行目录的对比方法
Nov 01 Python
一个可以套路别人的python小程序实例代码
Apr 09 Python
django使用django-apscheduler 实现定时任务的例子
Jul 20 Python
python实现日志按天分割
Jul 22 Python
python with语句的原理与用法详解
Mar 30 Python
PythonPC客户端自动化实现原理(pywinauto)
May 28 Python
python中线程和进程有何区别
Jun 17 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获取网络文件的实现代码
2010/01/01 PHP
php 无法载入mysql扩展
2010/03/12 PHP
浅析十款PHP开发框架的对比
2013/07/05 PHP
PHP基于简单递归函数求一个数阶乘的方法示例
2017/04/26 PHP
javascript验证上传文件的类型限制必须为某些格式
2013/11/14 Javascript
js实现百度联盟中一款不错的图片切换效果完整实例
2015/03/04 Javascript
JavaScript获取页面上被选中文字的方法技巧
2015/03/13 Javascript
jquery插件validation实现验证身份证号等
2015/06/04 Javascript
JS使用正则表达式除去字符串中重复字符的方法
2015/11/05 Javascript
Node.js中常规的文件操作总结
2016/10/13 Javascript
浅谈jQuery操作类数组的工具方法
2016/12/23 Javascript
使用nodejs下载风景壁纸
2017/02/05 NodeJs
Thinkjs3新手入门之添加一个新的页面
2017/12/06 Javascript
快速解决vue-cli不能初始化webpack模板的问题
2018/03/20 Javascript
React 实现拖拽功能的示例代码
2019/01/06 Javascript
jQuery对底部导航进行跳转并高亮显示的实例代码
2019/04/23 jQuery
vue中获取滚动table的可视页面宽度调整表头与列对齐(每列宽度不都相同)
2019/08/17 Javascript
Element DateTimePicker日期时间选择器的使用示例
2020/07/27 Javascript
[47:03]完美世界DOTA2联赛PWL S3 access vs LBZS 第一场 12.20
2020/12/23 DOTA
Python 的 with 语句详解
2014/06/13 Python
Python中的pprint折腾记
2015/01/21 Python
举例讲解Django中数据模型访问外键值的方法
2015/07/21 Python
可能是最全面的 Python 字符串拼接总结【收藏】
2018/07/09 Python
Python实现的服务器示例小结【单进程、多进程、多线程、非阻塞式】
2019/05/23 Python
python实现在函数中修改变量值的方法
2019/07/16 Python
简单了解Python读取大文件代码实例
2019/12/18 Python
Selenium 配置启动项参数的方法
2020/12/04 Python
趣味体育活动方案
2014/02/08 职场文书
2014普法依法治理工作总结
2014/12/18 职场文书
优秀员工推荐材料
2014/12/20 职场文书
道歉的话怎么说
2015/05/12 职场文书
大学班长竞选稿
2015/11/20 职场文书
2016元旦主持人开场白
2015/12/03 职场文书
Python爬虫入门案例之回车桌面壁纸网美女图片采集
2021/10/16 Python
简单聊聊Golang中defer预计算参数
2022/03/25 Golang
SQL SERVER中的流程控制语句
2022/05/25 SQL Server