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 ...
随机推荐
- java面试题----工厂模式大整理(面试问的较多)
在一次面试中了解到工厂模式在实际应用中的重要性,可以说工厂模式的应用随处可见,以下是百度百科对工厂模式的介绍 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式.著名的Jiv ...
- C#并行库(TaskParallelLibrary)用法 z
1. Task.Factory.StartNew(() => DoSomeWork());是异步的 下面的代码会先输出ddd,因为Task.Factory.Startnew不阻塞: var ta ...
- ASP.NET中引用dll“找不到指定模块"的完美解决办法 z
DllImport是System.Runtime.InteropServices命名空间下的一个属性类,其功能是提供从非托管DLL导出的函数的必要调用信息.DllImport属性应用于方法,要求最少要 ...
- 猿创|有赞的zan framework安装与使用[2]
下载并安装comoser curl -sS https://getcomposer.org/installer | php 结果各种超时 不能忍,打开迅雷下载installer:https://get ...
- WCF思考随笔一: WCF是干什么的?
对于WCF,之前知道是微软新一代开发框架的重要组成部分,是从之前Socket,COM,COM+,.NET Remoting,WebService等等系统内或系统间通讯解决方案发展而来,同时对各种解决方 ...
- 转 tcp协议里rst字段讲解
TCP协议的原理来谈谈rst复位攻击 http://russelltao.iteye.com/blog/1405349 几种TCP连接中出现RST的情况 https://blog.csdn.net/c ...
- Codeforces Round #515 (Div. 3) B. Heaters【 贪心 区间合并细节 】
任意门:http://codeforces.com/contest/1066/problem/B B. Heaters time limit per test 1 second memory limi ...
- ART_20190430
Algorithm-算法题 第一个只出现一次的字符 在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要 ...
- 【luogu P3884 [JLOI2009]二叉树问题】 题解
题目链接:https://www.luogu.org/problemnew/show/P3884 对方不想和你说话并向你扔了一个lca模板. #include <cstdio> #incl ...
- visual assist x vs2012不智能提示
今天装了visual assist x,但是在vs2012里不智能提示,在哪里看了看.找到了开关. 我英文不好.... 默认的话是不选中的.