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. 对synchronized(this)的一些理解

    一.当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块. ...

  2. Struts2的学习-通配符和session对象

    一. 取得session 3种方法1.context.getSession() -->>Map对象 2.HttpServletRequest request =(HttpServletRe ...

  3. 实验:将系统进程映射移到 Python 字典中

    参考官方文档,测试下列代码,把oracle的进程映射到python的字典中: [oracle@ycr python]$ more pro_get.py import reimport subproce ...

  4. nginx封IP脚本

    #!/bin/bash max= confdir=/etc/nginx/conf.d/blockips.conf logdir=/var/log/nginx/access.log echo " ...

  5. 阿里云上到底能运行SAP哪些产品?

    本文主要内容大部分来源于SAP已经发布的note:  2552731 - SAP Applications on Alibaba Cloud: Supported Products and IaaS ...

  6. iText生成PDF 格式报表

    1.导包 <dependency> <groupId>com.lowagie</groupId> <artifactId>itext</artif ...

  7. jackson简单实用

    ---------------------------------------------------------------------------------------------------- ...

  8. 【转】学习jar命令 创建和解压jar文件包

    java编程中每天都用不少jar文件,项目开发中不停地导包,在忙完了一天的工作,放下那些复杂的业务实现,不仅想问这些jar包怎么生成的,jar包有哪些独特的地方等等. 原来这些经常见到的jar包是ja ...

  9. Openresty最佳案例 | 第4篇:OpenResty常见的api

    转载请标明出处: http://blog.csdn.net/forezp/article/details/78616660 本文出自方志朋的博客 获取请求参数 vim /usr/example/exa ...

  10. Swift 中关于”??”操作符

    Swift 中关于”??”操作符 Swift 的语法在保证安全和健壮的基础上,又带有很多非常灵活的特性,比如 ?? 操作符就是其中一个.大家可能已经了解它,也可能有些同学不了解它,这里给大家整理了关于 ...