魔法方法、属性

------------------------

准备工作

为了确保类是新型类,应该把 _metaclass_=type 入到你的模块的最开始。

  1. class NewType(Object):
  2.   mor_code_here
  3. class OldType:
  4.   mor_code_here

在这个两个类中NewType是新类,OldType是属于旧类,如果前面加上 _metaclass_=type ,那么两个类都属于新类。

构造方法

构造方法与其的方法不一样,当一个对象被创建会立即调用构造方法。创建一个python的构造方法很简答,只要把init方法,从简单的init方法,转换成魔法版本的_init_方法就可以了。

  1. class FooBar:
  2. def __init__(self):
  3. self.somevar = 42
  4.  
  5. >>> f =FooBar()
  6. >>> f.somevar
  7. 42

重写一个一般方法

每一个类都可能拥有一个或多个超类(父类),它们从超类那里继承行为方法。

  1. class A:
  2. def hello(self):
  3. print 'hello . I am A.'
  4. class B(A):
  5.   pass
  6.  
  7. >>> a = A()
  8. >>> b = B()
  9. >>> a.hello()
  10. hello . I am A.

因为B类没有hello方法,B类继承了A类,所以会调用A 类的hello方法。

在子类中增加功能功能的最基本的方式就是增加方法。但是也可以重写一些超类的方法来自定义继承的行为。如下:

  1. class A:
  2. def hello(self):
  3. print 'hello . I am A.'
  4. class B(A):
  5. def hello(self):
  6. print 'hello . I am B'
  7.  
  8. >>> b = B()
  9. >>> b.hello()
  10. hello . I am B

特殊的和构造方法

重写是继承机制中的一个重要内容,对一于构造方法尤其重要。看下面的例子:

  1. class Bird:
  2. def __init__(self):
  3. self.hungry = True
  4. def eat(self):
  5. if self.hungry:
  6. print 'Aaaah...'
  7. self.hungry = False
  8. else:
  9. print 'No, thanks!'
  10.  
  11. >>> b = Bird()
  12. >>> b.eat()
  13. Aaaah...
  14. >>> b.eat()
  15. No, thanks!

这个类中定义了鸟有吃的能力, 当它吃过一次后再次就会不饿了,通过上面的执行结果可以清晰的看到。

那么用SongBird类来继承Bird 类,并且给它添加歌唱的方法:

  1. class Bird:
  2. def __init__(self):
  3. self.hungry = True
  4. def eat(self):
  5. if self.hungry:
  6. print 'Aaaah...'
  7. self.hungry = False
  8. else:
  9. print 'No, thanks!'
  10.  
  11. class SongBird(Bird):
  12. def __init__(self):
  13. self.sound = 'Squawk!'
  14. def sing(self):
  15. print self.sound
  16.  
  17. >>> s = SongBird()
  18. >>> s.sing()
  19. Squawk!
  20. >>> s.eat()
  21.  
  22. Traceback (most recent call last):
  23. File "<pyshell#26>", line 1, in <module>
  24. s.eat()
  25. File "C:/Python27/bird", line 6, in eat
  26. if self.hungry:
  27. AttributeError: 'SongBird' object has no attribute 'hungry'

异常很清楚地说明了错误:SongBird没有hungry特性。原因是这样的:在SongBird中,构造方法被重写,但新的构造方法没有任何关于初始化hungry特性的代码。为了达到预期的效果,SongBird的构造方法必须调用其超类Bird的构造方法来确保进行基本的初始化。

两种方法实现:

一 、调用未绑定的超类构造方法

  1. class Bird:
  2. def __init__(self):
  3. self.hungry = True
  4. def eat(self):
  5. if self.hungry:
  6. print 'Aaaah...'
  7. self.hungry = False
  8. else:
  9. print 'No, thanks!'
  10.  
  11. class SongBird(Bird):
  12. def __init__(self):
  13. Bird.__init__(self)
  14. self.sound = 'Squawk!'
  15. def sing(self):
  16. print self.sound
  17.  
  18. >>> s = SongBird()
  19. >>> s.sing()
  20. Squawk!
  21. >>> s.eat()
  22. Aaaah...
  23. >>> s.eat()
  24. No, thanks!

在SongBird类中添加了一行代码Bird.__init__(self) 。 在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(这称为绑定方法)。但如果直接调用类的方法,那么就没有实例会被绑定。这样就可以自由地提供需要的self参数(这样的方法称为未绑定方法)。

通过将当前的实例作为self参数提供给未绑定方法,SongBird就能够使用其超类构造方法的所有实现,也就是说属性hungry能被设置。

二、使用super函数

  1. __metaclass__ = type #表明为新式类
  2. class Bird:
  3. def __init__(self):
  4. self.hungry = True
  5. def eat(self):
  6. if self.hungry:
  7. print 'Aaaah...'
  8. self.hungry = False
  9. else:
  10. print 'No, thanks!'
  11.  
  12. class SongBird(Bird):
  13. def __init__(self):
  14. super(SongBird,self).__init__()
  15. self.sound = 'Squawk!'
  16. def sing(self):
  17. print self.sound
  18.  
  19. >>> s.sing()
  20. Squawk!
  21. >>> s.eat()
  22. Aaaah...
  23. >>> s.eat()
  24. No, thanks!

super函数只能在新式类中使用。当前类和对象可以作为super函数的参数使用,调用函数返回的对象的任何方法都是调用超类的方法,而不是当前类的方法。那就可以不同在SongBird的构造方法中使用Bird,而直接使用super(SongBird,self)。

属性

访问器是一个简单的方法,它能够使用getHeight 、setHeight 之样的名字来得到或者重绑定一些特性。如果在访问给定的特性时必须要采取一些行动,那么像这样的封装状态变量就很重要。如下:

  1. class Rectangle:
  2. def __init__(self):
  3. self.width = 0
  4. self.height = 0
  5. def setSize(self,size):
  6. self.width , self.height = size
  7. def getSize(self):
  8. return self.width , self.height
  9.  
  10. >>> r = Rectangle()
  11. >>> r.width = 10
  12. >>> r.height = 5
  13. >>> r.getSize()
  14. (10, 5)
  15. >>> r.setSize((150,100))
  16. >>> r.width
  17. 150

在上面的例子中,getSize和setSize方法一个名为size的假想特性的访问器方法,size是由width 和height构成的元组。

property 函数

property函数的使用很简单,如果已经编写了一个像上节的Rectangle 那样的类,那么只要增加一行代码:

  1. __metaclass__ = type
  2. class Rectangle:
  3. def __int__(self):
  4. self.width = 0
  5. self.height = 0
  6. def setSize(self,size):
  7. self.width, self.height = size
  8. def getSize(self):
  9. return self.width ,self.height
  10. size = property(getSize ,setSize)
  11.  
  12. >>> r = Rectangle()
  13. >>> r.width = 10
  14. >>> r.height = 5
  15. >>> r.size
  16. (10, 5)
  17. >>> r.size = 150,100
  18. >>> r.width
  19. 150

在这个新版的Retangle 中,property 函数创建了一个属性,其中访问器函数被用作参数(先取值,然后是赋值),这个属性命为size 。这样一来就不再需要担心是怎么实现的了,可以用同样的方式处理width、height 和size。

python基础教程(十)的更多相关文章

  1. (Python基础教程之十二)Python读写CSV文件

    Python基础教程 在SublimeEditor中配置Python环境 Python代码中添加注释 Python中的变量的使用 Python中的数据类型 Python中的关键字 Python字符串操 ...

  2. (Python基础教程之二十二)爬虫下载网页视频(video blob)

    Python基础教程 在SublimeEditor中配置Python环境 Python代码中添加注释 Python中的变量的使用 Python中的数据类型 Python中的关键字 Python字符串操 ...

  3. Python基础教程(第3版)PDF高清完整版免费下载|百度云盘

    百度云盘:Python基础教程(第3版)PDF高清完整版免费下载 提取码:gkiy 内容简介 本书包括Python程序设计的方方面面:首先从Python的安装开始,随后介绍了Python的基础知识和基 ...

  4. 改写《python基础教程》中的一个例子

    一.前言 初学python,看<python基础教程>,第20章实现了将文本转化成html的功能.由于本人之前有DIY一个markdown转html的算法,所以对这个例子有兴趣.可仔细一看 ...

  5. .Net程序员之Python基础教程学习----列表和元组 [First Day]

    一. 通用序列操作: 其实对于列表,元组 都属于序列化数据,可以通过下表来访问的.下面就来看看序列的基本操作吧. 1.1 索引: 序列中的所有元素的下标是从0开始递增的. 如果索引的长度的是N,那么所 ...

  6. python基础教程笔记—即时标记(详解)

    最近一直在学习python,语法部分差不多看完了,想写一写python基础教程后面的第一个项目.因为我在网上看到的别人的博客讲解都并不是特别详细,仅仅是贴一下代码,书上内容照搬一下,对于当时刚学习py ...

  7. css3基础教程十六变形与动画animation

    前面我们讲过的变形与动画一般都是通过鼠标的单击.获得焦点,被点击或对元素进行一定改变后以后触发效果的,那么有没有像Flash一样自动播放的动画效果呢?答案当然是肯定的,这就是我们今天要讲到的anima ...

  8. python基础教程(一)

    之所以选择py交易有以下几点:1.python是胶水语言(跨平台),2.python无所不能(除了底层),3.python编写方便(notepad++等文本编辑器就能搞事情),4.渗透方面很多脚本都是 ...

  9. Python基础教程2上的一处打印缺陷导致的代码不完整#1

    #1对代码的完善的 出现打印代码处缺陷截图: 图片上可以看到,定义的request根本没有定义它就有了.这个是未定义的,会报错的,这本书印刷问题,这个就是个坑,我也是才发现.花了点时间脱坑. 现在发完 ...

  10. python基础教程(第二版)

    开始学习python,根据Python基础教程,把里面相关的基础章节写成对应的.py文件 下面是github上的链接 python基础第1章基础 python基础第2章序列和元组 python基础第3 ...

随机推荐

  1. Ubuntu彻底删除/卸载mysql,php,apache

    一.卸载删除 mysql 1 sudo apt-get autoremove --purge mysql-server-5.02 sudo apt-get remove mysql-server3 s ...

  2. (转)mybatis常用jdbcType数据类型

    1 MyBatis 通过包含的jdbcType类型 BIT FLOAT CHAR TIMESTAMP OTHER UNDEFINED TINYINT REAL VARCHAR BINARY BLOB ...

  3. Object-C 里面的animation动画效果,核心动画

    #import "CoreAnimationViewController.h" @interface CoreAnimationViewController ()@property ...

  4. 看望朋友(家达)--->>对事情的专注及时间效率学习

    本意是想去堕落街吃完饭就回寝室休息了,结果偶遇尹阳,便说是一同去走走.路上边走边聊,我便提议去十教楼顶,十教是全学校最高的教学楼,这也是刘智学长给我说的.在十教楼顶的那种感觉,特别想吹口琴,可惜没有带 ...

  5. webIDE 第二篇博文

    这是我做webIDE过程中的第二篇博文,之所以隔了这么长时间没更,因为确实是没有啥进度啊,没什么可写的,现在虽然依然没啥进度,但中途遇到很多坑,这些坑还是有记录下来的必要的. 因个人水平问题,可能有的 ...

  6. 我的学习之路_第三十四章_jsp

    jsp 在只有servlet时,输出页面内容比较麻烦(成本高,java代码中输出HTML标签),所以需要一种技术,主要是HTML页面的代码(HTML,css,js),可以嵌入java代码,来实现动态页 ...

  7. R语言 write.xlsx() 写入同一excel,及同一sheet注意

    write.xlsx(x, file, sheetName="Sheet1", col.names=TRUE, row.names=TRUE, append=FALSE, show ...

  8. Tornado session 插件 pycket 定制时间和时间续租

    功能描述:10分钟用户没有任何操作,跳转到登录页面. 分析:这个功能用session就能实现(由于pycket 的session内容是存储在memcached或者redis里面的.所以,session ...

  9. Spring+SpringMVC+MyBatis+easyUI整合进阶篇(二)RESTful API实战笔记(接口设计及Java后端实现)

    写在前面的话 原计划这部分代码的更新也是上传到ssm-demo仓库中,因为如下原因并没有这么做: 有些使用了该项目的朋友建议重新创建一个仓库,因为原来仓库中的项目太多,结构多少有些乱糟糟的. 而且这次 ...

  10. java正则表达式提取地址中的ip和端口号

    由于我需要用到java正则表达式提取地址中的ip和端口号,所以我就写了一个demo,测试一下,下面是demo public class Test0810_1 { public static void ...