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 相关文章推荐
windows下wxPython开发环境安装与配置方法
Jun 28 Python
python爬虫入门教程之点点美女图片爬虫代码分享
Sep 02 Python
python中如何正确使用正则表达式的详细模式(Verbose mode expression)
Nov 08 Python
python生成多个只含0,1元素的随机数组或列表的实例
Nov 12 Python
Python输出\u编码将其转换成中文的实例
Dec 15 Python
int在python中的含义以及用法
Jun 27 Python
python实现PID算法及测试的例子
Aug 08 Python
jenkins配置python脚本定时任务过程图解
Oct 29 Python
PyCharm 2019.3发布增加了新功能一览
Dec 08 Python
解决Jupyter notebook更换主题工具栏被隐藏及添加目录生成插件问题
Apr 20 Python
Python同时处理多个异常的方法
Jul 28 Python
Python使用lambda抛出异常实现方法解析
Aug 20 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
一个更简单的无限级分类菜单代码
2007/01/16 PHP
PHP中获取内网用户MAC地址(WINDOWS/linux)的实现代码
2011/08/11 PHP
php动态生成缩略图并输出显示的方法
2015/04/20 PHP
PHP面向对象程序设计实例分析
2016/01/26 PHP
PHP的PDO事务与自动提交
2019/01/24 PHP
jquery仿京东导航/仿淘宝商城左侧分类导航下拉菜单效果
2013/04/24 Javascript
JS判断移动端访问设备并加载对应CSS样式
2014/06/13 Javascript
js实现select跳转菜单新窗口效果代码分享(超简单)
2015/08/21 Javascript
jQuery Easy UI中根据第一个下拉框选中的值设置第二个下拉框是否可以编辑
2016/11/29 Javascript
Node.js的特点详解
2017/02/03 Javascript
jquery实现焦点轮播效果
2017/02/23 Javascript
兼容浏览器的js事件绑定函数(详解)
2017/05/09 Javascript
npm国内镜像 安装失败的几种解决方案
2017/06/04 Javascript
vue如何在自定义组件中使用v-model
2018/05/14 Javascript
微信小程序实现下拉菜单切换效果
2020/03/30 Javascript
Vue实现简易翻页效果源码分享
2018/11/08 Javascript
简单了解JavaScript中的执行上下文和堆栈
2019/06/24 Javascript
python 中的列表解析和生成表达式
2011/03/10 Python
python 将字符串转换成字典dict
2013/03/24 Python
跟老齐学Python之折腾一下目录
2014/10/24 Python
用Python实现通过哈希算法检测图片重复的教程
2015/04/02 Python
Linux下使用python自动修改本机网关代码分享
2015/05/21 Python
Python中判断输入是否为数字的实现代码
2018/05/26 Python
Python实现数据可视化看如何监控你的爬虫状态【推荐】
2018/08/10 Python
详解用python实现基本的学生管理系统(文件存储版)(python3)
2019/04/25 Python
Python实现数值积分方式
2019/11/20 Python
python实现简单颜色识别程序
2020/02/19 Python
python实现磁盘日志清理的示例
2020/11/05 Python
细说CSS3中的选择符
2008/10/17 HTML / CSS
CSS3制作炫酷带方向感应的鼠标滑过图片3D动画
2016/03/16 HTML / CSS
大专生工程监理求职信
2013/10/04 职场文书
员工晚婚的请假条
2014/02/08 职场文书
一月红领巾广播稿
2014/02/11 职场文书
《彭德怀和他的大黑骡子》教学反思
2014/04/12 职场文书
论文评审意见
2015/06/05 职场文书
2015年秋季小学开学标语
2015/07/16 职场文书