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学习之魔法方法的更多相关文章

  1. Python学习8——魔法方法、特性和迭代器

    Python中很多名称比较古怪,开头和结尾都是两个下划线.这样的拼写表示名称有特殊意义,因此绝不要在程序中创建这样的名称.这样的名称中大部分都是魔法(方法)的名称.如果你的对象实现了这些方法,他们将在 ...

  2. python类之魔法方法

    python类之魔法方法: class A(object): def __init__(self,x): self.x = x def __neg__(self): print('-v') def _ ...

  3. python里的魔法方法1(构造与析构)

    魔法方法——构造与析构 1.python编程的魔法方法: (1)魔法方法总是被双下划线包围,例如__init__: (2)魔法方法是面向对象的python的一切. 2.__new__(class[,… ...

  4. Python中的魔法方法

    1.什么是魔法方法? 魔法方法就是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一 ...

  5. 零基础学习python_魔法方法(41-48课)(迭代器)

    接下来这个为啥要叫魔法方法呢,额,这个嘛我是跟小甲鱼的视频取的名字一样的,因为会讲比较多杂的东西,有... 魔法方法详细阅读地址:http://bbs.fishc.com/thread-48793-1 ...

  6. python基础之魔法方法

    由于hexo自带的markdown渲染引擎对双下划线做了转义,在正文中看到的魔法方法前后都没有双下划线 setattr.getattr.delattr 可以拦截对对象属性的访问 setattr函数是用 ...

  7. python中类的魔法方法

    __xx__这种方法,在Python中均称为魔法方法 1.__init__(self) 该方法的作用是初始化对象 在创建对象时被默认调用,不需要手动调节 self参数不需要开发者传递,解释器会自动将创 ...

  8. python学习 —— post请求方法的应用

    声明:本篇仅基于兴趣以及技术研究而对B站曾经发生过的抢楼事件背后相关技术原理进行研究而写.请不要将其作为私利而对B站以及B站用户体验造成影响!谢谢合作!若本文对B站及其用户带来困扰,请联系本人删除本文 ...

  9. Python面向对象之魔法方法/双下方法

    1.__new__ and __init__ 这两个方法都是在实例化的时候执行,__new__ 在 __init__ 之前执行,并且 如果实例化的时候封装属性,__new__也是必须要传的,而且__n ...

随机推荐

  1. Python单元测试框架unittest使用方法讲解

    这篇文章主要介绍了Python单元测试框架unittest使用方法讲解,本文讲解了unittest概述.命令行接口.测试案例自动搜索.创建测试代码.构建测试套件方法等内容,需要的朋友可以参考下   概 ...

  2. spring对数据库的操作、spring中事务管理的介绍与操作

    jdbcTemplate的入门 创建maven工程 此处省略 导入依赖 <!-- https://mvnrepository.com/artifact/org.springframework/s ...

  3. 面向切面编程-AOP的介绍

    AOP简介 AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象 ...

  4. htmlunit模拟登录

    htmlunit jar项目路径http://sourceforge.net/projects/htmlunit/files/htmlunit/ demo代码如下 public class AutoL ...

  5. XP环境安装request包报错:离线安装packages: certifi urllib3 idna chardet

    分别下载 request certifi urllib3 idna chardet 安装包 数据包下载地址:https://pypi.org/ 解压到python安装目录 使用cmd命令进入..\py ...

  6. PS软件怎么把视频转成gif动态图?

    PS软件怎么把视频转成gif动态图?Adobe PhotoShop软件的最新版本是可以编辑视频的,并且可以将视频转换为GIF动态图,使用也很简单,下面分享ps制作gif动态图的教程,需要的朋友可以参考 ...

  7. HDU 5723 最小生成树上的期望

    题意:求最小生成树,和任意两个点之间距离的期望 官方题解: 最后求两遍点的积的时候,还是要判断父子关系. 注意 long long #include <bits/stdc++.h> usi ...

  8. 【[ZJOI2008]骑士】

    这道题好暴力啊 发现自己刚学\(OI\)的时候对着这道题写了一个大搜索 发现已经看不懂了 果然我现在菜到连一年半前的我都不如了 这其实是一个基环树\(dp\)啦,基环树上的最大点独立集 其实很简单,我 ...

  9. nodejs protobuff node-protobuf c++ windows扩展安装笔记

    https://www.npmjs.com/package/node-protobuf 按照作者所说的办法在windows平台安装的办法,先到google的github下载2.6.1版本的protob ...

  10. Could..... not preload global game manager

    发布PC版后出现这个错误,是没有破解成功,卸载后重新安装破解就可以了 http://www.cocoachina.com/bbs/read.php?tid=84587