鱼C论坛

 找回密码
 立即注册
查看: 1776|回复: 7

[技术交流] 01 初探__init__()方法

[复制链接]
发表于 2017-9-5 20:14:52 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 和vvv 于 2017-11-18 15:22 编辑
01 初探__init__()方法

通过重写特殊方法来完成Python内部机制的调用,在Python中是很普遍的。例如len()函数就可以重写一个类的__len__()方法。这意味着对于像__len__()这样的通用公共接口,任何类都可以实现它。任何一个类都可以重写一个像__len__()这样的特殊方法,这样一种机制构成了Python多态机制的一部分。任何实现了__len__()函数的类都会响应通用公共接口len(x)中的len()函数。

(1)隐式的基类-object

每个Python类的定义都会隐式继承自object类,它的定义非常简单,几乎什么行为都不包括。我们可以创建一个object实例,但很多事情无法完成,因为很多特殊方法的调用程序都会抛出异常。

现在来看看例子:
  1. class Student:
  2.     def hello(self):
  3.         print('hello')
复制代码
然后我们这样:
  1. #判断Student的类别,相当于函数type()
  2. Student.__class__
复制代码
结果:
  1. type
复制代码
说明Student是一个类。这样也可以:
  1. type(Student)
复制代码
结果:
  1. type
复制代码
我们来看看Student类是否还有父类,用什么方法呢?为了判断object是不是Student的父类,我们可以使用issubclass()方法:
  1. issubclass(Student,object)
复制代码
结果:
  1. True
复制代码
说明Student是object的子类。我们也可以这样:
  1. Student.__base__
复制代码
或者:
  1. Student.__class__.__base__
复制代码
结果都是:
  1. object
复制代码
相应地,派生自object类中的对象方法也将继承各自相应的默认实现。在某些情况下,基类中一些特殊方法的默认行为也正是我们所需要的。但是呢,人难免有需求,这时我们就需要重写这些方法了。


(2)基类中的__init__()方法

对象的生命周期:
无标题.png
object作为所有类的基类,已经为__init__()方法提供了默认实现。一般来说,我们不需要重写这个函数。这时,在创建对象时将不会产生其他变量的实例。

对于继承自object的子类,总可以对它的属性进行扩展。
  1. class Rectangle:
  2.     def area(self):
  3.         return self.width * self.length
复制代码
匆匆地瞄一眼,感觉这段代码有点问题,width和length是从哪里冒出来的。 但运行之后,并没有报错。再好好地想了想,应该是这样的。Python的变量不需要事先声明,直接使用就可以了。上面的类不就是这样的嘛!self.width代表width是本类的属性。只是,我们没有对width和length进行初始化。


看这样是否有问题:
  1. r = Rectangle()
  2. r.area()
复制代码
想想,

看看:
  1. ---------------------------------------------------------------------------
  2. AttributeError                            Traceback (most recent call last)
  3. <ipython-input-10-848c6814f3c7> in <module>()
  4.       1 r = Rectangle()
  5. ----> 2 r.area()

  6. <ipython-input-8-9390a30b29ca> in area(self)
  7.       1 class Rectangle:
  8.       2     def area(self):
  9. ----> 3         return self.width * self.length

  10. AttributeError: 'Rectangle' object has no attribute 'width'
复制代码
果然出现问题了。原来如此,width和height根本无实际意义,只是一个标签。就相当于你直接在>>>直接输入a,你看它会不会报错。因此,我们要先让其能够width和length成为变量(变量包括变量名和变量值),才行。
  1. r = Rectangle()
  2. r.width = 5
  3. r.length = 6
  4. r.area()
复制代码
结果:
  1. 30
复制代码
现在,就可以了。


虽然这种延迟赋值的实现方式在Python中是合法的,但是却给调用者带来了潜在的困惑,因此要尽量避免这样的方法。那我们怎样来为类进行初始化呢?这时,我们就需要重写基类的__init__()方法了。

(3)在基类中实现__init__()方法

通过实现__init__()方法来初始化一个对象。每当创建一个对象时,Python将会先创建一个空对象,然后调用该对象的__init__()函数。
__init__()方法提供了对象内部变量以及其他一些一次性过程的初始化操作。

现在呢,来看看一个例子:
  1. class Card:
  2.     def __init__( self, rank, suit ):
  3.         self.suit = suit
  4.         self.rank = rank
  5.         self.hard, self.soft = self._points()

  6. class NumberCard( Card ):
  7.     def _points( self ):
  8.         return int(self.rank), int(self.rank)
  9.    
  10. class AceCard( Card ):
  11.     def _points( self ):
  12.         return 1, 11

  13. class FaceCard( Card ):
  14.     def _points( self ):
  15.         return 10, 10
复制代码
在基类中,我们对suit和rank进行了初始化,我们可以这样使用:
  1. c = Card('A','黑桃')
  2. print( c.rank, c.suit, c.hard, c.soft )
复制代码
结果:
A 黑桃 0 0

  1. n = NumberCard('5','红桃')
  2. print( n.rank, n.suit, n.hard, n.soft)
复制代码
结果:
5 红桃 5 5



  1. a = AceCard('6','方块')
  2. print( a.rank, a.suit, a.hard, a.soft)
复制代码
结果:
6 方块 1 11



  1. f = FaceCard('6','方块')
  2. print( f.rank, f.suit, f.hard, f.soft)
复制代码
结果:
6 方块 10 10

这里一个常见的多态设计,每个子类为_points()方法提供特有的功能。所有的子类拥有相同的方法名和属性。

今天就到这里了。



想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-6 05:16:38 | 显示全部楼层
很好 非常感谢楼主宝贵的经验。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-9-6 10:36:15 | 显示全部楼层
并不是经验,是我自己做的笔记
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-7 08:52:27 | 显示全部楼层
学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-7 10:03:37 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-7 10:24:36 | 显示全部楼层
学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-9-7 10:33:03 | 显示全部楼层
路过
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-11-9 10:04:09 | 显示全部楼层
1111
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-19 05:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表