计算机科学和Python编程导论week6

2018-08-01  本文已影响50人  瘦长的丰一禾

面向对象最重要的概念就是类(Class)和实例(Instance),类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。

参考《Python编程导论 第二版》第8章类与面向对象编程
Python3面向对象编程

8.1抽象数据类型和类

In [30]: class IntSet(object):
    ...:    """IntSet是一个整数集合"""
    ...:    #关于实现(不是抽象)的信息
    ...:    #集合的值由一个整数数组self.vals表示。
    ...:    #集合中的每个整数在self.vals中只出现一次。
    ...:    def __init__(self):
    ...:        """创建一个空的整数集合"""
    ...:        self.vals = []
    ...:    def insert(self, e):
    ...:        """假设e是整数,将e插入self"""
    ...:        if e not in self.vals:
    ...:            self.vals.append(e)
    ...:    def member(self, e):
    ...:        """假设e是整数
    ...:        如果e在self中,则返回True,否则返回False"""
    ...:        return e in self.vals
    ...: 
    ...:    def remove(self, e):
    ...:        """假设e是整数,从self中删除e
    ...:        如果e不在self中,则抛出ValueError异常"""
    ...:        try:
    ...:            self.vals.remove(e)
    ...:        except:
    ...:            raise ValueError(str(e) + ' not found')
    ...:    def getMembers(self):
    ...:        """返回一个包含self中元素的列表
    ...:        对元素不进行排序"""
    ...:        return self.vals[:]
    ...:    def __str__(self):
    ...:        """返回一个表示self的字符串"""
    ...:        self.vals.sort()
    ...:        result = ''
    ...:        for e in self.vals:
    ...:            result = result + str(e) + ','
    ...:        return '{' + result[:-1] + '}' #-1 可以忽略最后的逗号
    ...: 

In [31]: print(type(IntSet),type(IntSet.insert))
<class 'type'> <class 'function'>

In [32]: s = IntSet()
In [33]: s.insert(3)
In [35]: print(s.member(3))
True
In [36]: s.insert(4)
In [37]: s
Out[37]: <__main__.IntSet at 0x1101fd30>
In [41]: print(s)
{3,4}
In [40]: s.getMembers()
Out[40]: [3, 4]

8.1.2 使用类记录学生与教师

In [43]: import datetime
    ...: class Person(object):
    ...:    def __init__(self, name):
    ...:        """创建一个人"""
    ...:        self.name = name
    ...:        try:
    ...:            lastBlank = name.rindex(' ')
    ...:            self.lastName = name[lastBlank+1:]
    ...:        except:
    ...:            self.lastName = name
    ...:            self.birthday = None
    ...:    def getName(self):
    ...:        """返回self的全名"""
    ...:        return self.name
    ...:    def getLastName(self):
    ...:        """返回self的姓"""
    ...:        return self.lastName
    ...:    def setBirthday(self, birthdate):
    ...:        """假设birthday是datetime.date类型
    ...:        将self的生日设置为birthday"""
    ...:        self.birthday = birthdate
    ...:    def getAge(self):
    ...:        """返回self的当前年龄,用日表示"""
    ...:        if self.birthday == None:
    ...:            raise ValueError
    ...:        return (datetime.date.today() - self.birthday).days
    ...:    def __lt__(self, other):
    ...:        """如果self按字母顺序位于other之前,则返回True,否则返回False。
    ...:        首先按照姓进行比较,如果姓相同,就按照全名比较"""
    ...:        if self.lastName == other.lastName:
    ...:            return self.name < other.name
    ...:        return self.lastName < other.lastName
    ...:    def __str__(self):
    ...:        """返回self的全名"""
    ...:        return self.name
    ...: 

In [44]: me = Person('Michael Guttag')
    ...: him = Person('Barack Hussein Obama')
    ...: her = Person('Madonna')
    ...: 

In [45]: print(him.getLastName())
    ...: him.setBirthday(datetime.date(1961, 8, 4))
    ...: her.setBirthday(datetime.date(1958, 8, 16))
    ...: print(him.getName(), 'is', him.getAge(), 'days old')
    ...: 
Obama
Barack Hussein Obama is 20816 days old

In [47]: pList = [me, him, her]
    ...: for p in pList:
    ...:     print(p)
    ...: print('----------------------------------------')
    ...: pList.sort()
    ...: for p in pList:
    ...:     print(p)
    ...:     
Michael Guttag
Barack Hussein Obama
Madonna
----------------------------------------
Michael Guttag
Madonna
Barack Hussein Obama

8.2 继承

In [48]: class MITPerson(Person):
    ...:    nextIdNum = 0 #identification number
    ...:    def __init__(self, name):
    ...:        Person.__init__(self, name)
    ...:        self.idNum = MITPerson.nextIdNum
    ...:        MITPerson.nextIdNum += 1
    ...:    def getIdNum(self):
    ...:        return self.idNum
    ...:    def __lt__(self, other):
    ...:        return self.idNum < other.idNum
    ...: 

In [49]: p1 = MITPerson('Barbara Beaver')
    ...: print(str(p1) + '\'s id number is ' + str(p1.getIdNum()))
    ...: 
Barbara Beaver's id number is 0

In [50]: p1 = MITPerson('Mark Guttag')
    ...: p2 = MITPerson('Billy Bob Beaver')
    ...: p3 = MITPerson('Billy Bob Beaver')
    ...: p4 = Person('Billy Bob Beaver')
    ...: print('p1 < p2 =', p1 < p2)
    ...: print('p3 < p2 =', p3 < p2)
    ...: print('p4 < p1 =', p4 < p1)
    ...: 
p1 < p2 = True
p3 < p2 = False
p4 < p1 = True

In [52]: print('p1 < p4 =', p1 < p4)
Traceback (most recent call last):

  File "<ipython-input-52-46143f00caa4>", line 1, in <module>
    print('p1 < p4 =', p1 < p4)

  File "<ipython-input-48-602df1c0e123>", line 10, in __lt__
    return self.idNum < other.idNum

AttributeError: 'Person' object has no attribute 'idNum'
# 运行时系统会调用与p1的类型关联的__lt__操作符,也就是定义在MITPerson类中的函数。
# 创建student类

In [14]: class Student(object):
    ...:     def __init__(self, name, score):
    ...:         self.name = name
    ...:         self.score = score
    ...:     def print_score(self):
    ...:         print("%s:%s" % (self.name, self.score))
    ...:     def get_grade(self):
    ...:         if self.score >= 90:
    ...:             return 'A'
    ...:         elif self.score >= 60:
    ...:             return 'B'
    ...:         else:
    ...:             return 'C'
    ...:         

In [15]: lisa = Student('Lisa', 99)
    ...: bart = Student('Bart', 59)
    ...: print(lisa.name, lisa.get_grade())
    ...: print(bart.name, bart.get_grade())
    ...: 
Lisa A
Bart C

多重继承

In [53]: class Student(MITPerson):
    ...:    pass
    ...: class UG(Student):
    ...:    def __init__(self, name, classYear):
    ...:        MITPerson.__init__(self, name)
    ...:        self.year = classYear
    ...:    def getClass(self):
    ...:        return self.year
    ...: class Grad(Student):
    ...:    pass
    ...: 

In [54]: p5 = Grad('Buzz Aldrin')
    ...: p6 = UG('Billy Beaver', 1984)
    ...: print(p5, 'is a graduate student is', type(p5) == Grad)
    ...: print(p5, 'is an undergraduate student is', type(p5) == UG)
    ...: 
Buzz Aldrin is a graduate student is True
Buzz Aldrin is an undergraduate student is False

面向对象的核心思想:封装和信息隐藏。
封装是指:将数据属性和操作数据属性的方法打包在一起。信息隐藏是指:使属性在类之外不可见。

在Python 3中,可以使用命名惯例使属性在类之外不可见。当一个属性的名称以开头但不以结束时,这个属性在类外就是不可见的。如下:

In [55]: class infoHiding(object):
    ...:    def __init__(self):
    ...:        self.visible = 'Look at me'
    ...:        self.__alsoVisible__ = 'Look at me too'
    ...:        self.__invisible = 'Don\'t look at me directly'
    ...:    def printVisible(self):
    ...:        print(self.visible)
    ...:    def printInvisible(self):
    ...:        print(self.__invisible)
    ...:    def __printInvisible(self):
    ...:        print(self.__invisible)
    ...:    def __printInvisible__(self):
    ...:        print(self.__invisible)
    ...:   

In [56]: test = infoHiding()
    ...: print(test.visible)
    ...: print(test.__alsoVisible__)
    ...: print(test.__invisible)
    ...: 
Look at me
Look at me too
Traceback (most recent call last):

  File "<ipython-input-56-8ba28fd4db07>", line 4, in <module>
    print(test.__invisible)

AttributeError: 'infoHiding' object has no attribute '__invisible'


In [57]: test = infoHiding()
    ...: test.printInvisible()
    ...: test.__printInvisible__()
    ...: test.__printInvisible()
    ...: 
Don't look at me directly
Don't look at me directly
Traceback (most recent call last):

  File "<ipython-input-57-b6445e79430b>", line 4, in <module>
    test.__printInvisible()

AttributeError: 'infoHiding' object has no attribute '__printInvisible'


In [58]: class subClass(infoHiding):
    ...:     def __init__(self):
    ...:         print('from subclass', self.__invisible)
    ...: testSub = subClass()
    ...: 
Traceback (most recent call last):

  File "<ipython-input-58-4a0a22384a1a>", line 4, in <module>
    testSub = subClass()

  File "<ipython-input-58-4a0a22384a1a>", line 3, in __init__
    print('from subclass', self.__invisible)

AttributeError: 'subClass' object has no attribute '_subClass__invisible'

类的继承

In [37]: class A(object):
    ...:     def __init__(self):
    ...:         self.a = 1
    ...:     def x(self):
    ...:         print ("A.x")
    ...:     def y(self):
    ...:         print ("A.y")
    ...:     def z(self):
    ...:         print ("A.z")
    ...: 
    ...: class B(A):
    ...:     def __init__(self):
    ...:         A.__init__(self)
    ...:         self.a = 2
    ...:         self.b = 3
    ...:     def y(self):
    ...:         print ("B.y")
    ...:     def z(self):
    ...:         print ("B.z")
    ...: 
    ...: class C(object):
    ...:     def __init__(self):
    ...:         self.a = 4
    ...:         self.c = 5
    ...:     def y(self):
    ...:         print ("C.y")
    ...:     def z(self):
    ...:         print ("C.z")
    ...: 
    ...: class D(C, B):
    ...:     def __init__(self):
    ...:         C.__init__(self)
    ...:         B.__init__(self)
    ...:         self.d = 6
    ...:     def z(self):
    ...:         print ("D.z")
    ...:         

In [38]: obj = D()

In [39]: obj.a
Out[39]: 2

In [40]: obj.b
Out[40]: 3

In [41]: obj.c
Out[41]: 5

In [42]: obj.d
Out[42]: 6

In [43]: obj.x()
A.x

In [44]: obj.y
Out[44]: <bound method C.y of <__main__.D object at 0x00000000113F90F0>>

In [45]: obj.y()
C.y

In [46]: obj.z()
D.z

视频试题:

In [1]: class Clock(object):
   ...:     def __init__(self,time):
   ...:         self.time = time
   ...:     def print_time(self):
   ...:         time = '6:30'
   ...:         print (self.time)
   ...: clock = Clock('5:30')
   ...: clock.print_time()
   ...: 
5:30

In [4]: class Clock(object):
   ...:     def __init__(self,time):
   ...:         self.time = time
   ...:     def print_time(self,time):
   ...:         print (time)
   ...: clock = Clock('5:30')
   ...: clock.print_time('10:30')
   ...: 
10:30

In [5]: class Clock(object):
   ...:     def __init__(self,time):
   ...:         self.time = time
   ...:     def print_time(self):
   ...:         print (self.time)
   ...: boston_clock = Clock('5:30')
   ...: paris_clock = boston_clock
   ...: paris_clock.time = '10:30'
   ...: boston_clock.print_time()
   ...: 
10:30

In [32]: class Spell(object):
    ...:     def __init__(self, incantation, name):
    ...:         self.name = name
    ...:         self.incantation = incantation
    ...: 
    ...:     def __str__(self):
    ...:         return self.name + ' ' + self.incantation + '\n' + self.getDescription()
    ...: 
    ...:     def getDescription(self):
    ...:         return 'No description'
    ...: 
    ...:     def execute(self):
    ...:         print (self.incantation)    
    ...: 
    ...: 
    ...: class Accio(Spell):
    ...:     def __init__(self):
    ...:         Spell.__init__(self, 'Accio', 'Summoning Charm')
    ...: 
    ...: class Confundo(Spell):
    ...:     def __init__(self):
    ...:         Spell.__init__(self, 'Confundo', 'Confundus Charm')
    ...: 
    ...:     def getDescription(self):
    ...:         return 'Causes the victim to become confused and befuddled.'
    ...: 
    ...: def studySpell(spell):
    ...:     print (spell)
    ...:     

In [33]: spell = Accio()
    ...: spell.execute()
    ...: studySpell(spell)
    ...: studySpell(Confundo())
    ...: 
Accio
Summoning Charm Accio
No description
Confundus Charm Confundo
Causes the victim to become confused and befuddled.

参考链接:
6.00.1X 计算机科学和PYTHON编程导论

上一篇下一篇

猜你喜欢

热点阅读