Python学习之魔法方法

Python中会看到前后都加双下划线的函数名,例如 __init__(self),这类写法在Python中具有特殊的含义。如果对象使用了这类方法中的某一个,那么这个方法将会在特殊的情况下被执行,然而几乎不会直接调用此类方法。
如果没有兼容旧版本Python代码的需要,我们在编写代码时应将所有类的写为新式类并且使用super函数这样的特性。
在Python3.0中没有"旧式"的类,也不需要侠士的子类化Object或者将元类设置为type(代码起始行__metaclass__=type).那是因为所有的类都是隐式的成为Object的子类。如果没有明确超类的话,就会直接子类化;否则间接子类化。
Python中的重写
先看代码
class A:
def hello(self):
print('hello i\'m a')
class B(A):
pass
a=A()
a.hello()
b=B()
b.hello()
输出结果:
hello i'm a
hello i'm a
B类继承A类,实例化B对象后可以调用A类中的hello函数,但并不能满足自己需求,我不仅要调用A类中的函数,而且还需要执行满足自己的命令(比如打印hello b)。此时我们就可以在子类中重写超类的函数以满足自己的需求。
修改代码如下:
class A:
def hello(self):
print('hello i\'m a')
class B(A):
def hello(self):
print('hello i\'m b')
a=A()
a.hello()
b=B()
b.hello()
输出结果:
hello i'm a
hello i'm b
Python中的构造方法
构造方法与其他方法不同,当一个对象被创建后,会立即调用构造方法。
重写一般方法和特殊的构造方法:
了解过继承的概念后我们知道,每个类都可能拥有一个或者多个超类,子类从父类那里继承父类的一些行为方式。不仅如此,我们也可以重写一些超类的方法来自定义继承行为。
class Bird:
def __init__(self):
self.hungry=True
def eat(self):
if self.hungry:
print('我在吃')
self.hungry=False
else:
print('我吃饱了,谢谢') sb=Bird()
sb.eat()
sb.eat()
打印结果:
我在吃
我吃饱了,谢谢
通过代码可知道,鸟吃饱以后,将饥饿状态改为Flase,说明小鸟吃饱了,当在调用eat函数时候,则打印我吃饱了,谢谢。这是在通一个类中的__init__函数的使用。来看扩展案例。吃是鸟类的基本特征,可以将Bird作为鸟类的基类。现在我们写一个会唱歌的鸟,因为我们已经写好了一个鸟的基类,此时仅需继承它之后,我们的鸟不仅会唱歌而且默认的学会了吃的技能。
class Bird:
def __init__(self):
self.hungry=True
def eat(self):
if self.hungry:
print('ahhh')
self.hungry=False
else:
print('no thanks') class SongBird(Bird):
def __init__(self): self.sound='Squawk' def sing(self):
print(self.sound)
sb=SongBird()
sb.sing()
sb.eat()
sb.eat()
打印结果:
Traceback (most recent call last):
Squawk
File "F:/Python培训/博客园随笔专用/文件操作/文件读写.py", line , in <module>
sb.eat()
File "F:/Python培训/博客园随笔专用/文件操作/文件读写.py", line , in eat
if self.hungry:
AttributeError: 'SongBird' object has no attribute 'hungry'
不幸的是,我们的鸟可以触发唱歌的功能,但当调用父类的吃的功能时,就抛出了异常。再看父类中定义的eat函数,启动eat函数需要设置hungry属性。但不解的是,我们已经继承了鸟的基类Bird,Bird里也定义了hungry为什么不起作用呢。那是因为hungry属性是在当父类调用自己的构造函数时才起作用。由此可见,SingBird继承了Bird的所有功能,却未触发Bird的初始化功能。修改以下代码
class Bird:
def __init__(self):
self.hungry=True
def eat(self):
if self.hungry:
print('ahhh')
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)
sb=SongBird()
sb.sing()
sb.eat()
sb.eat()
输出结果:
Squawk
ahhh
no thanks
通过代码可以知道,我们在SongBird的初始化类时,调用了Bird的初始化函数。因此,Bird的构造函数得以触发。现在我们的鸟,不仅能唱歌而且具备基类中吃的行为。
再看它执行过程。SongBird在初始化自身的同时,又将自己作为参数传递给它的父类,也就是告诉父类,你在造我的时候,要赋予我天生的技能(自己知道温饱)。也就是hungry属性被设置。
使用Super函数
以上方法是3.0以前的写法,新式类中将使用super函数解决以上问题。
class Bird:
def __init__(self):
self.hungry=True
def eat(self):
if self.hungry:
print('ahhh')
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)
sb=SongBird()
sb.sing()
sb.eat()
sb.eat()
当前的类和对象被当做参数调用,而调用函数返回的对象的任何方法都是调用超类的方法。总结:显示的传递子类和子类对象并且调用构造函数但隐式的却是在执行父类的构造方法。
基本的映射和序列规则

__len__:返回集合中所含项目的数量。对于序列来说,返回的是元素的个数,对于映射来说返回的是 键值对的数量。
__getitem__(self,key):返回与所给键对应的值。对于序列,键应该是0~n-1的整数(n是长度),对于映射,可以是任何类型的键。
__setitem__(self,key,value):按一定方式存储和key相关的value.该值可以用__getitem__来获取。 注意:只能为可以修改的对象定义这个方法。
__delitem__(self,key):该方法在对一部分对象使用del语句时调用。
属性
Python学习之魔法方法的更多相关文章
- Python学习8——魔法方法、特性和迭代器
Python中很多名称比较古怪,开头和结尾都是两个下划线.这样的拼写表示名称有特殊意义,因此绝不要在程序中创建这样的名称.这样的名称中大部分都是魔法(方法)的名称.如果你的对象实现了这些方法,他们将在 ...
- python类之魔法方法
python类之魔法方法: class A(object): def __init__(self,x): self.x = x def __neg__(self): print('-v') def _ ...
- python里的魔法方法1(构造与析构)
魔法方法——构造与析构 1.python编程的魔法方法: (1)魔法方法总是被双下划线包围,例如__init__: (2)魔法方法是面向对象的python的一切. 2.__new__(class[,… ...
- Python中的魔法方法
1.什么是魔法方法? 魔法方法就是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一 ...
- 零基础学习python_魔法方法(41-48课)(迭代器)
接下来这个为啥要叫魔法方法呢,额,这个嘛我是跟小甲鱼的视频取的名字一样的,因为会讲比较多杂的东西,有... 魔法方法详细阅读地址:http://bbs.fishc.com/thread-48793-1 ...
- python基础之魔法方法
由于hexo自带的markdown渲染引擎对双下划线做了转义,在正文中看到的魔法方法前后都没有双下划线 setattr.getattr.delattr 可以拦截对对象属性的访问 setattr函数是用 ...
- python中类的魔法方法
__xx__这种方法,在Python中均称为魔法方法 1.__init__(self) 该方法的作用是初始化对象 在创建对象时被默认调用,不需要手动调节 self参数不需要开发者传递,解释器会自动将创 ...
- python学习 —— post请求方法的应用
声明:本篇仅基于兴趣以及技术研究而对B站曾经发生过的抢楼事件背后相关技术原理进行研究而写.请不要将其作为私利而对B站以及B站用户体验造成影响!谢谢合作!若本文对B站及其用户带来困扰,请联系本人删除本文 ...
- Python面向对象之魔法方法/双下方法
1.__new__ and __init__ 这两个方法都是在实例化的时候执行,__new__ 在 __init__ 之前执行,并且 如果实例化的时候封装属性,__new__也是必须要传的,而且__n ...
随机推荐
- 腾讯云微信小程序域名变更指南
1 . 将域名添加到云解析里面, 将解析的地址指向已有的小程序负载均衡地址: https://console.qcloud.com/cns 将域名添加到解析列表 添加成功之后,点击解析按钮,添加二级域 ...
- shell中和RDA中的alert日志中文乱码
客户端字符集无法识别中文,只能下载到本机使用nodepad++查看
- POSIX 线程详解(经典必看)
http://www.cnblogs.com/sunminmin/p/4479952.html 总共三部分: 第一部分:POSIX 线程详解 ...
- LA 4327 多段图
题目链接:https://vjudge.net/contest/164840#problem/B 题意: 从南往北走,横向的时间不能超过 c: 横向路上有权值,求权值最大: 分析: n<=100 ...
- LG3690 【【模板】Link Cut Tree (动态树)】
题目 终于去写\(LCT\)了 这个大爷讲的挺好的 板子 #include<algorithm> #include<iostream> #include<cstring& ...
- 设置IE浏览器的默认下载路径
实现效果: 知识运用: Default Download Directory键 实现代码: private void button2_Click(object sender, EventArgs e) ...
- 【题解】P1516 青蛙的约会(Exgcd)
洛谷P1516:https://www.luogu.org/problemnew/show/P1516 思路: 设两只青蛙跳了T步 则A的坐标为X+mT B的坐标为Y+nT 要使他们相遇 则满足: ...
- 数据库——MySQL——单表查询
单表查询语法: SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY field LIMIT 限制条数 关键字的执行 ...
- ZooKeeper下载安装(Windows版本)
进入Apache ZooKeeper官方网站进行下载,https://zookeeper.apache.org/releases.html 这里我们选择zookeeper-3.4.12版本进行下载 百 ...
- Data Guard 知识 (来自网络)
更改DG工作模式前提参数得设定合理. Physical standby直接从主库接受archived log,然后直接做基于block的物理恢复(更新或调整变化的block),所以physical s ...