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中使用urllib2获取http请求状态码的代码例子
Jul 07 Python
Python列表生成器的循环技巧分享
Mar 06 Python
Python优先队列实现方法示例
Sep 21 Python
python互斥锁、加锁、同步机制、异步通信知识总结
Feb 11 Python
Python制作exe文件简单流程
Jan 24 Python
学习python可以干什么
Feb 26 Python
Python爬虫实现爬取百度百科词条功能实例
Apr 05 Python
pandas DataFrame 警告(SettingWithCopyWarning)的解决
Jul 23 Python
python实现屏保程序(适用于背单词)
Jul 30 Python
Python中模块(Module)和包(Package)的区别详解
Aug 07 Python
np.newaxis 实现为 numpy.ndarray(多维数组)增加一个轴
Nov 30 Python
利用django model save方法对未更改的字段依然进行了保存
Mar 28 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
SONY SRF-40W电路分析
2021/03/02 无线电
第一节--面向对象编程
2006/11/16 PHP
php循环语句 for()与foreach()用法区别介绍
2012/09/05 PHP
php遍历文件夹所有文件子文件夹函数代码
2013/11/27 PHP
Yii框架分页技术实例分析
2019/08/30 PHP
jquery正则表达式验证(手机号、身份证号、中文名称)
2015/12/31 Javascript
AngularJS仿苹果滑屏删除控件
2016/01/18 Javascript
JS实现的简易拖放效果示例
2016/12/29 Javascript
Javascript基础回顾之(二) js作用域
2017/01/31 Javascript
微信小程序下拉刷新PullDownRefresh的使用方法
2018/11/29 Javascript
Vue.js@2.6.10更新内置错误处机制Fundebug同步支持相应错误监控
2019/05/13 Javascript
用webpack4开发小程序的实现方法
2019/06/04 Javascript
js实现上传图片并显示图片名称
2019/12/18 Javascript
Python httplib,smtplib使用方法
2008/09/06 Python
Python中optionParser模块的使用方法实例教程
2014/08/29 Python
常见的python正则用法实例讲解
2016/06/21 Python
Python开发SQLite3数据库相关操作详解【连接,查询,插入,更新,删除,关闭等】
2017/07/27 Python
Anaconda下安装mysql-python的包实例
2018/06/11 Python
浅谈pycharm使用及设置方法
2019/09/09 Python
Python 爬虫实现增加播客访问量的方法实现
2019/10/31 Python
使用python批量转换文件编码为UTF-8的实现
2020/04/03 Python
Python 下载Bing壁纸的示例
2020/09/29 Python
Python Pandas数据分析工具用法实例
2020/11/05 Python
使用HTML5 Canvas绘制圆角矩形及相关的一些应用举例
2016/03/22 HTML / CSS
便携式太阳能系统的创新者:GOAL ZERO
2018/02/04 全球购物
美国户外烹饪产品购物网站:Outdoor Cooking
2020/01/10 全球购物
基层党组织公开承诺书
2014/03/28 职场文书
校庆标语集锦
2014/06/25 职场文书
中文专业自荐书
2014/06/29 职场文书
学校安全工作汇报材料
2014/08/16 职场文书
入党积极分子学习党的纲领思想汇报
2014/09/13 职场文书
乡村教师党员四风问题对照检查材料思想汇报
2014/10/08 职场文书
2015年秋学期教研工作总结
2015/10/14 职场文书
《迟到》教学反思
2016/02/24 职场文书
动画「进击的巨人」第86话播出感谢绘公开
2022/03/21 日漫
AngularJS实现多级下拉框
2022/03/25 Javascript