0911--https://www.cnblogs.com/fnng/archive/2013/05/08/3066054.html

魔法方法、属性

准备工作

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

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

在这两个类中NewType是新类,OldType是属于旧类,如果前面嘉善

构造方法

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

  1. class FooBar:
  2. def __init__(self):
  3. self.somevar = 42
  4.  
  5. #运行程序
  6. >>> f = FooBar()
  7. >>> f.somevar
  8. 42

重写一个一般方法

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

(Python pass是空语句,是为了保持程序结构的完整性。pass 不做任何事情,一般用做占位语句。)

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

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

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

  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. #运行程序
  9. >>> b = B()
  10. >>> b.hello()
  11. 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. #运行程序
  12. >>> b = Bird()
  13. >>> b.eat()
  14. Aaaah...
  15. >>> b.eat()
  16. 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 = 'qiuqiu~~'
  14. def sing(self):
  15. print (self.sound)
  16.  
  17. #运行程序
  18. >>> s = SongBird()
  19. >>> s.sing()
  20. qiuqiu~~
  21. >>> s.eat()
  22. Traceback (most recent call last):
  23. File "<pyshell#13>", line 1, in <module>
  24. s.eat()
  25. File "E:/study/python/demo0911/重写添加方法.py", line 5, 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 = 'qiuqiu~~'
  15. def sing(self):
  16. print (self.sound)
  17.  
  18. #运行程序
  19. >>> s = SongBird()
  20. >>> s.sing()
  21. qiuqiu~~
  22. >>> s.eat()
  23. Aaaah...
  24. >>> s.eat()
  25. No,thanks!

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

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

二、使用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 = 'qiuqiu~~'
  16. def sing(self):
  17. print (self.sound)
  18.  
  19. #运行程序
    >>> s = SongBird()
  20. >>> s.sing()
  21. qiuqiu~~
  22. >>> s.eat()
  23. Aaaah...
  24. >>> s.eat()
  25. 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. #运行程序
  11. >>> r = Rectangle()
  12. >>> r.width = 10
  13. >>> r.height = 5
  14. >>> r.getSize()
  15. (10, 5)
  16. >>> r.setSize((150,100))
  17. >>> r.width
  18. 150

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

property函数

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

  1. __metaclass__ = type
  2. class Rectangle:
  3. def __init__(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. #运行程序
  13. >>> r = Rectangle()
  14. >>> r.width = 10
  15. >>> r.height = 5
  16. >>> r.size
  17. (10, 5)
  18. >>> r.size = 110,120
  19. >>> r.width
  20. 110

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

python学习记录(九)的更多相关文章

  1. Python学习记录day6

    title: Python学习记录day6 tags: python author: Chinge Yang date: 2016-12-03 --- Python学习记录day6 @(学习)[pyt ...

  2. Python学习记录day5

    title: Python学习记录day5 tags: python author: Chinge Yang date: 2016-11-26 --- 1.多层装饰器 多层装饰器的原理是,装饰器装饰函 ...

  3. Python学习记录day8

    目录 Python学习记录day8 1. 静态方法 2. 类方法 3. 属性方法 4. 类的特殊成员方法 4.1 __doc__表示类的描述信息 4.2 __module__ 和 __class__ ...

  4. Python学习记录day7

    目录 Python学习记录day7 1. 面向过程 VS 面向对象 编程范式 2. 面向对象特性 3. 类的定义.构造函数和公有属性 4. 类的析构函数 5. 类的继承 6. 经典类vs新式类 7. ...

  5. Python学习记录:括号配对检测问题

    Python学习记录:括号配对检测问题 一.问题描述 在练习Python程序题的时候,我遇到了括号配对检测问题. 问题描述:提示用户输入一行字符串,其中可能包括小括号 (),请检查小括号是否配对正确, ...

  6. Python学习笔记九

    Python学习笔记之九 为什么要有操作系统 管理硬件,提供接口. 管理调度进程,并且将多个进程对硬件的竞争变得有序. 操作系统发展史 第一代计算机:真空管和穿孔卡片 没有操作系统,所有的程序设计直接 ...

  7. 实验楼Python学习记录_挑战字符串操作

    自我学习记录 Python3 挑战实验 -- 字符串操作 目标 在/home/shiyanlou/Code创建一个 名为 FindDigits.py 的Python 脚本,请读取一串字符串并且把其中所 ...

  8. Spring学习记录(九)---通过工厂方法配置bean

    1. 使用静态工厂方法创建Bean,用到一个工厂类 例子:一个Car类,有brand和price属性. package com.guigu.spring.factory; public class C ...

  9. 【Python学习之九】模块

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 python3.6 一.模块的使用和安装模块和C语言中的头文件以及Ja ...

  10. 我的Python学习记录

    Python日期时间处理:time模块.datetime模块 Python提供了两个标准日期时间处理模块:--time.datetime模块. 那么,这两个模块的功能有什么相同和共同之处呢? 一般来说 ...

随机推荐

  1. 【tf.keras】AdamW: Adam with Weight decay

    论文 Decoupled Weight Decay Regularization 中提到,Adam 在使用时,L2 与 weight decay 并不等价,并提出了 AdamW,在神经网络需要正则项时 ...

  2. 删除centos自带的openjdk

    [wj@master hadoop]$ rpm -qa | grep javajava-1.7.0-openjdk-1.7.0.191-2.6.15.5.el7.x86_64python-javapa ...

  3. 在IIS上发布netcore项目

    保证电脑上有.net core sdk或者.net core runtime; 需要安装AspNetCoreModule托管模块:DotNetCore.2.0.5-WindowsHosting.exe ...

  4. 1、使用 as 而不要用 is

    public class ShouldAsNotIs { public void ShouldAs() { object a = new ShouldAsNotIs(); var b = a as S ...

  5. 使用 git 将代码推送到多个仓库

    使用 git 将代码推送到多个仓库 起因     起初,在 GitHub 建了一个仓库,200+ 的 commits .后来(终于在眼泪中明白...误

  6. cogs 728. [网络流24题] 最小路径覆盖问题 匈牙利算法

    728. [网络流24题] 最小路径覆盖问题 ★★★☆   输入文件:path3.in   输出文件:path3.out   评测插件时间限制:1 s   内存限制:128 MB 算法实现题8-3 最 ...

  7. Linux删除文件 清除缓存

    相信很多测试 经常会经历开发叫你清除缓存这种事. 那我们要怎么清呢? 一.首先,确认你要清除的缓存在哪个目录下,然后切换到该目录下,比如 我现在知道我的的缓存目录是在newerp这个目录下,则如图 二 ...

  8. <a>标签的href和onclick属性【转】

    1链接的onclick 事件被先执行,其次是href属性下的动作(页面跳转,或 javascript 伪链接): 2假设链接中同时存在href 与onclick,如果想让href 属性下的动作不执行, ...

  9. java实现FTP文件下载

    package com.vingsoft.util;/*** @author 作者:dujj* @version 创建时间:2020年1月13日 下午5:53:39*/import java.io.F ...

  10. C++ 链式继承下的虚函数列表

    目录 1.虚函数列表的位置 2.虚函数列表的内容 3.链式继承中虚函数列表的内容   注: 虚函数列表 又称为虚表, vtbl , 指向它的指针称为vptr, vs2019中称为__vfptr 操作系 ...