第一章——Python的面相对象编程:定义类

参考blog
参考2
python3 magic method
python魔法方法知乎指南

0.简介

在此之前,我在cousera上看了不少python写数据结构和算法的视频课程,推荐两个比较基础、讲解详细的python课:

  1. 都柏林理工学院的Damian Gordon课程《Programming and Algorithms 》
  2. 密歇根大学Charles Severance课程《Programming for Everybody (Getting Started with Python)》。该教授把python编程课讲得非常有趣,非常适合入门,墙裂推荐
  3. Let's learn python:youtube上很好的python入门课,讲得清楚,但用例较简单。

但是由于视频获取知识太慢,看书比较直接,《Problem Solving with Algorithms and Data Structures using Python》是目前我看到的最好的用python写数据结构和算法的web book,没有之一。

以下使用python3.5

1.课程笔记

总结:

  1. 类的作用:提供模板、赋初值、将相同属性的变量放在一起
  2. f1为类的实例,由于赋了初值保证了分母有参数
  3. print实例对象为该对象的地址
  4. ’+‘ 都对应了_ add _
    python中的操作符文档Mapping Operators to Functions
class Fraction:#类名通常是大写开头,objec它是指类是从那一类继承下来的,object类,这是所有类最终都会继承的类。
    
    def __init__(self,top,bottom=2):  #定制类的初值
        self.num = top
        self.den = bottom

    def show(self):
        print(self.num, "/", self.den)

    def __add__(self, secondnum):  #定制类的加法
        newnum = self.num * secondnum.den + self.den * secondnum.num
        newden = self.den * secondnum.den
        return Fraction(newnum, newden)

f1 = Fraction(5)
f2 = Fraction(1,4)
print(f2)
f3 = f1 + f2
f3.show()

>> 5 / 2
<__main__.Fraction object at 0x10197ae80>
22 / 8

结果:

>>> (2).__add__(2)
4
>>> 2+2
4

电路继承

基本门的构建分为三层:
1)LogicGate:定义1.gate的名字,2.一个输出,3.申明作用
2)BinaryGate:定义1.两个输入,2.对输入赋值
3)AndGate:定义1.定义作用
门的连接,形成电路:

class LogicGate(object):   # 特点:有输入和输出(给初值None)、测试的实验的名字,例如test1
    def __init__ (self, number):
        self.name = number
        self.output = None

    def getName(self):
        return self.name

    def getAnswer(self):
        self.output = self.process()  # 实现自己的逻辑运算
        return self.output

class BinaryGate(LogicGate):  # 继承了LogicGate,,但是有两个输入
    def __init__(self, number):
        LogicGate.__init__(self, number)     #继承上父辈的构造函数
        self.pinA = None                     #定义有两个输入
        self.pinB = None

    def getPinA(self):
        return int(input('Enter the pinA '+ self.getName()+'-->'))

    def getPinB(self):
        return int(input('Enter the pinB '+ self.getName()+'-->'))


class AndGate(BinaryGate):
    def __init__(self, number):
        BinaryGate.__init__(self,number)
    def process(self):         # 定义了具体行为
        A = self.getPinA()
        B = self.getPinB()
        if A==1 and B ==1:
            return 1
        else:
            return 0

>>> g1 = AndGate("G1")
>>> g1.getOutput()
Enter Pin A input for gate G1-->1
Enter Pin B input for gate G1-->0
0

注意:在实际工业界中常用super来表示继承关系,请看我放在Python文件夹中的“类”补充(来自youtube课程Let's learn python

class Charactor(object):
    def __init__(self, name):
        self.health = 100
        self.name = name
    def show(self):
        print(self.name)
        
class Student(Charactor):
    def __init__(self, name, forgename):
        super(Student,self).__init__(name)
        self.forge = Forge(forgename)
        
class Forge(object):
    def __init__(self, forgename):
        self.name = forgename

Me = Student('fan','ivy')
print(Me.name)
print(Me.forge.name)


>>>fan
>>>ivy

对于super(Student, self).init()这样理解:super(Student, self)首先找到Student的父类(就是类Charactor),然后把Student类的对象self转换为Charactor类的对象,然后“被转换”的Charactor类对象调用自己的init函数。

2.思考

2.1为什么要使用类?类的好处是哪些?面向对象编程(Object Oriented Programming)和结构化的编程有什么不同?

  1. 结构体,将一类属性进行封装
  2. 结构体内部的函数可以直接使用,外部的函数需要调用
  3. 继承,简洁至上
  4. 类(模板)和实例(用例)的概念更容易被人类接受

3.课后习题

习题地址

3.1补充知识点

str( )和repr( )比较

相同:改变对象实例的打印或显示输出,返回可读性强的字符串

class Fraction:
    def __init__(self, top, down):
        self.Top = top
        self.Down = down
        
 >>>F1 = Fraction(9,5)
 >>>print (F1) 
 <__main__.Fraction object at 0x101988160>    #打印出开发者看到的类地址

不同str( )返回用户看到的字符串,而repr( )返回程序开发者看到的字符串,也就是说,repr() 是为调试服务

    def __repr__(self):
        return "num:{}, den:{}".format(self.Top, self.Down)
 
>>>F1 = Fraction(9,5)
>>>>print (F1) 
num:9, den:5

3.2 Fraction类部分

def gcd(m, n):  # common number
    while m % n != 0:
        oldm = m
        oldn = n

        m = oldn
        n = oldm % oldn
    return n

class Fraction:
    def __init__(self, top, down):
#####  q4-检查分子分母是否是整数,否则异常处理  #####
        if isinstance(top, int) == False or isinstance(down, int) == False:
            raise Exception("the numerator and denominator are both integers!")
        self.Top = top
        self.Down = down

    def show(self):
        print('the fractor is', self.Top,'/',self.Down)
##### q9-__repr__  #####
    def __repr__(self):
        return "num:{}, den:{}".format(self.Top, self.Down)


#####  q2-add with gcd #####
    def __add__(self, other):
        newDown = self.Down * other.Down
        newTop = self.Top * other.Down + self.Down * other.Top
        common = gcd(newDown, newTop)
        return Fraction(newTop//common, newDown//common)

#####  q8-__iadd__override += in Python  #####
##### m = m + n #####
    def __iadd__(self, other):
        newDown = self.Down * other.Down
        newTop = self.Top * other.Down + self.Down * other.Top
        common = gcd(newDown, newTop)
        return Fraction(newTop//common, newDown//common)


    def __sub__(self,other):
        newDown = self.Down * other.Down
        newTop = self.Top * other.Down - self.Down * other.Top
        common = gcd(newDown, newTop)
        return Fraction(newTop//common, newDown//common)


#####  q4-Implement  __gt__, __ge__, __lt__, __le__, __ne__  ######
    def __gt__(self, other):
        if self.Top * other.Down > self.Down * other.Top:
            return True
        else:
            return False

    def __ge__(self, other):  ## 大于等于 ##
        if self.Top * other.Down >= self.Down * other.Top:
            return True
        else:
            return False

    def __lt__(self, other):
        if self.Top * other.Down < self.Down * other.Top:
            return True
        else:
            return False

    def __le__(self, other):
        if self.Top * other.Down <= self.Down * other.Top:
            return True
        else:
            return False

    def __ne__(self, other):
        if self.Top * other.Down != other.Top * self.Down:
            return True
        else:
            return False

######  q1   #####

    def getTop(self):
        return self.Top

    def getDown(self):
        return self.Down

def main():
    F1 = Fraction(9,5)
    print (F1)
    F1.show()
    F2 = Fraction(1,5)
    print(F2)
    #
    print("F1+F2:")
    (F1+F2).show()

    print("F1-F2:")
    (F1-F2).show()

    print (F1>F2)
    print (F1>=F2)
    print (F1!=F2)
    print (F1<F2)

    F1+=F2
    F1.show()

main()

3.3 数字电路继承部分

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容