魔法方法、属性

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

准备工作

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

class NewType(Object):
  mor_code_here
class OldType:
  mor_code_here

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

构造方法

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

class FooBar:
def __init__(self):
self.somevar = 42 >>> f =FooBar()
>>> f.somevar
42

重写一个一般方法

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

class A:
def hello(self):
print 'hello . I am A.'
class B(A):
  pass >>> a = A()
>>> b = B()
>>> a.hello()
hello . I am A.

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

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

class A:
def hello(self):
print 'hello . I am A.'
class B(A):
def hello(self):
print 'hello . I am B' >>> b = B()
>>> b.hello()
hello . I am B

特殊的和构造方法

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

class Bird:
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print 'Aaaah...'
self.hungry = False
else:
print 'No, thanks!' >>> b = Bird()
>>> b.eat()
Aaaah...
>>> b.eat()
No, thanks!

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

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

class Bird:
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print 'Aaaah...'
self.hungry = False
else:
print 'No, thanks!' class SongBird(Bird):
def __init__(self):
self.sound = 'Squawk!'
def sing(self):
print self.sound >>> s = SongBird()
>>> s.sing()
Squawk!
>>> s.eat() Traceback (most recent call last):
File "<pyshell#26>", line 1, in <module>
s.eat()
File "C:/Python27/bird", line 6, in eat
if self.hungry:
AttributeError: 'SongBird' object has no attribute 'hungry'

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

两种方法实现:

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

class Bird:
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print 'Aaaah...'
self.hungry = False
else:
print 'No, thanks!' class SongBird(Bird):
def __init__(self):
Bird.__init__(self)
self.sound = 'Squawk!'
def sing(self):
print self.sound >>> s = SongBird()
>>> s.sing()
Squawk!
>>> s.eat()
Aaaah...
>>> s.eat()
No, thanks!

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

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

二、使用super函数

__metaclass__ = type  #表明为新式类
class Bird:
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print 'Aaaah...'
self.hungry = False
else:
print 'No, thanks!' class SongBird(Bird):
def __init__(self):
super(SongBird,self).__init__()
self.sound = 'Squawk!'
def sing(self):
print self.sound >>> s.sing()
Squawk!
>>> s.eat()
Aaaah...
>>> s.eat()
No, thanks!

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

属性

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

class Rectangle:
def __init__(self):
self.width = 0
self.height = 0
def setSize(self,size):
self.width , self.height = size
def getSize(self):
return self.width , self.height >>> r = Rectangle()
>>> r.width = 10
>>> r.height = 5
>>> r.getSize()
(10, 5)
>>> r.setSize((150,100))
>>> r.width
150

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

property 函数

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

__metaclass__ = type
class Rectangle:
def __int__(self):
self.width = 0
self.height = 0
def setSize(self,size):
self.width, self.height = size
def getSize(self):
return self.width ,self.height
size = property(getSize ,setSize) >>> r = Rectangle()
>>> r.width = 10
>>> r.height = 5
>>> r.size
(10, 5)
>>> r.size = 150,100
>>> r.width
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. maven引入已经拥有的jar包

    <!-- https://mvnrepository.com/artifact/jfree/jcommon --><dependency>    <groupId> ...

  2. (转)sql union和union all的用法及效率

    1 熟悉union的相关操作 UNION指令的目的是将两个SQL语句的结果合并起来.从这个角度来看, 我们会产生这样的感觉,UNION跟JOIN似乎有些许类似,因为这两个指令都可以由多个表格中撷取资料 ...

  3. Spring 学习笔记(七)—— 切入点表达式

    为了能够灵活定义切入点位置,Spring AOP提供了多种切入点指示符. execution———用来匹配执行方法的连接点 语法结构:   execution(   方法修饰符  方法返回值  方法所 ...

  4. VerilogHDL可综合设计的注意事项

    可综合的语法已经记录得差不多了,剩下一些遗留的问题,在这里记录一下吧. 一.逻辑设计 (1)组合逻辑设计 下面是一些用Verilog进行组合逻辑设计时的一些注意事项: ①组合逻辑可以得到两种常用的RT ...

  5. 13 年的 Bug 调试经验总结(来自蜗牛学院)

    在<Learning From Your Bugs>一文中,我写了关于我是如何追踪我所遇到的一些最有趣的bug. 最近,我回顾了我所有的194个条目,看看有什么经验教训是我可以学习的.下面 ...

  6. metasploit快速入门

    今天没上班,在小黑屋里看了一个一百多页的书<metasploit新手指南>,在此将笔记分享给大家.欢迎大家批评指正,共同学习进步.     metasploit新手指南 笔记 kali 0 ...

  7. Java中parse()和valueOf(),toString()的区别

    1.parse()是SimpleDateFomat里面的方法,你说的应该是parseInt()或parsefloat()这种方法吧, 顾名思义 比如说parseInt()就是把String类型转化为i ...

  8. java学习笔记随记

    12月21日 其中1  2 是赋值 Source----format 格式化调整代码 shift+ctrl+F Ctrl +d 删除行 代码规范, 首字母大写 System.out.println其中 ...

  9. HTML 超链接 表格

    1...超链接 <a href="网址" target="_blank"> 被点击的文字</a> 如果把 target 属性设置为&qu ...

  10. 使用MySQL-Proxy读写分离时的注意事项

    在动手操作前最好先安装好MySQL-Proxy,并配置好MySQL主从服务器.补充:新版MySQL已经内建支持 延迟问题 读写分离不能回避的问题之一就是延迟,可以考虑Google提供的SemiSync ...