接下来的学习安排
我选修的选修课'机器学习'的学习压力有点大,毕竟不是科班出身还是有很多东西要补充的,可能全栈学习到面向对象后会暂缓全栈编程的学习,转向机器学习->人工智能的学习(主要学习选修的机器学习中的sklearn模块).另外会开一个随笔类,记录我的机器学习进度.
第一部分:面向对象相关.
第二部分:网络编程.[暂缓]
第三部分:并发编程(多派几个人去,完成某事时候效率和速度更快一些).[暂缓]
今日大纲
1.用对比函数式编程的方式引出面向对象。
2.面向对象代码如何编写?
3.面向的3大特性:
a.封装
b.继承
c.多态
内容回顾:
1.面向过程:从上到下累代码(类似写作文一样)
2.函数式编程和面向过程的好处:方便,简洁,快速,提高代码的重现性。
3.为什么要将某些函数写在指定文件中? 对函数进行一个归类
详细内容:
一.函数和面向对象的对比
######### Round1 开发一个消息提醒的功能(邮件/短信/微信 的提醒) 函数vs面向对象。############# #函数式编程 def email(ads,text): ''' 发送邮件给alex :return: ''' pass def msg(pnum,text): ''' 发送短信给alex :return: ''' pass def wechat(wcid,text): ''' 发送微信给alex :return: ''' pass if 1==1: email('alex@sb.com','negu购买了一个py全栈课程') msg('18888888','negu购买了一个py全栈课程') wechat('alex123','negu购买了一个py全栈课程') #面向对象式编程 class Message:#将函数放到class代码块里边,在参数里面必须加上一个'self' def email(self,ads, text): ''' 发送邮件给alex :return: ''' print(ads,text) def msg(self,pnum, text): ''' 发送短信给alex :return: ''' print(pnum,text) def wechat(self,wcid, text): ''' 发送微信给alex :return: ''' print(wcid, text) if 1==1: obj = Message() obj.email('alex@sb.com','negu购买了一个py全栈课程')#在python中会自动为这个self传参数.直接就是传obj,这个语法是py内部用的. obj.msg('18888888','negu购买了一个py全栈课程') obj.wechat('alex123','negu购买了一个py全栈课程') 对比: 函数定义简单/调用简单,面向对象:定义复杂/调用复杂/但做了一个归类,将某些类似功能写在了一起. 总结: 1.函数式编程可能比面向对象更好. 2.python中支持函数和面向对象两种编程方式 3.面向对象方式的格式为:定义:class name:#定义了一个'类' def name1(self,....):#在类中编写了一个'方法' pass ...... 调用: variable = name()#创建了一个'对象' variable.name1(.....) #通过对象调用其中的一个方法 ############## Round2 ############ #实现一个功能-打印 ''' negu/22岁/男/努力编程 negu/22岁/男/开车去东北 negu/22岁/男/一个人呆着 ''' #函数式编程 def programming(name,age,gender): data = '%s今年%s岁,性别为%s,喜欢编程.'%(name,age,gender) def driving(name,age,gender): data = '%s今年%s岁,性别为%s,喜欢开车去东北.' % (name,age,gender) def lonely(name,age,gender): data = '%s今年%s岁,性别为%s,喜欢一个人呆着.' % (name,age,gender) programming('negu','22','male') driving('negu','22','male') lonely('negu','22','male')#参数在反复传递,有点low. #想让那个函数自己去取,不用反复传递. #面向对象版 class Negu:#当类后面加括号时init这个方法就会被自动执行.且被执行的时候必须往init里面传指定的参数. def __init__(self,name,age,gender):#一个特殊的方法,必须这么写,本质上是将一些指打包放在一个地,往obj里面赋值.(构造方法.)进行数据的初始化. self.n1 = name#往空的容器里面传了name self.n2 = age self.n3 = gender#__init__就像一个人的旅行背包,拿着东西取东西的时候方便. def programming(self): data = '%s今年%s岁,性别为%s,喜欢编程.' % (self.n1, self.n2,self.n3) print(data) def driving(self): data = '%s今年%s岁,性别为%s,喜欢开车去东北.' % (self.n1, self.n2,self.n3) print(data) def lonely(self): data = '%s今年%s岁,性别为%s,喜欢一个人呆着.' % (self.n1, self.n2,self.n3) print(data) obj = Negu('negu','22','male')#可以把这个实例化的对象当作一个容器或者字典. print(obj.n1)#negu obj.programming() obj.driving() obj.lonely() #小结:在类方法内部可以调用其它的方法,无论用什么方法来调用函数self永远等于外面的那个obj.
面向对象到底如何编写?
a.规则:
class Foo: def _init_(self,name) : self.name = 'xxx'
b.什么时候写?如何写?
方式一:归类->提取公共值#新手专用
方式二:正向进行编写,在某个类中就编写当前类的相关所有代码.分类的时候将所有相关的类,功能以及属性都放在这里就好了,+提取公众值. #老手常用
class File: def __init__(self,filepath): self.filepath = filepath def file_read(self,filepath): pass def file_update(self,filepath): pass def file_delete(self,filepath): pass def file_add(self,filepath): pass class Excel: def excel_read(self,filepath): pass def excel_update(self,filepath): pass def excel_delete(self,filepath): pass def excel_add(self,filepath): pass
三大特性:封装\继承\多态 (面试:谈谈你对面向对象的认识?)
封装:
将相关功能封装到一个类中;
将数据封装到一个对象中
继承:
* 编写方式class(父类名):...
* 支持多继承(先找左再找右)
* 为什么要有多继承->提高代码的复用性
* 练习部分:找到self到底是谁(谁的对象),从对象开始找.
多态:
多种形态或者多种状态
鸭子模型:你蒙上眼睛,这个鸭子能呱呱叫,那么你面前的就是鸭子
def fun(arg):
arg[0]#无法确定是元组还是列表,是多种形态.xx[]=呱呱叫
所以arg既可以是列表也可是元组.
继承详解
#基本写法 class GrandFather: def func3(self): print('f3') class Father(GranFather): def func2(self): print('f2') class Name(Father):#在定义类名时候加(别的类名)创建父子继承关系.可以使用父类里面的方法. def func1(self):#子类,派生类 print('f1') #原则,先去子类找,没有去爷爷类找. obj = Name() obj.func1() obj.func2() obj.func3() #为何要有继承->是为了复用,提高代码的重用性. #多继承 class Base1: def show(self): print('base1 show') pass class Base2: def show(self): print('base2 show') pass #打印base1的show class Foo(Base1,Base2): pass Fooobj = Foo() Fooobj.show()#打印的是base1 show,若方法名一样则优先执行左侧父类的方法. 关于继承的一些练习题 # ###############练习题############## # ###########题1######### # class Base3: # def f1(self): # print('Base3 f1') # class Foo1(Base3): # def f2(self): # print('Foo f2') # #问题1: # objFoo = Foo1() # objFoo.f2()#出现什么? -> 出现'Foo f2' # #问题2: # ObjBase3 = Base3() #ObjBase3.f2 #出现了什么? ->会报错,父类不会去子类中找方法. ###### 题2 ########## # class Base3: # def f1(self): # print('Base3 f1') # def f3(self): # self.f1()#此时的self还是obj也就是Foo # print('Base3 f3') # class Foo1(Base3): # def f1(self): # print('Foo f1') # # def f2(self): # print('Foo f2') # self.f3() # # objFoo = Foo1() # objFoo.f2()#会出现什么? # #obj是哪一个类,那么执行方法时,就从该类开始找 # ''' # Foo f2 # Foo f1 # foo f3 # ''' # objBase = Base3() # objBase.f3() # ''' # Base3 f1 # foo f3 # ''' #总结:self是哪个类的对象就从该类开始找.(自己没有就找父类). ####### 题3 ####### class Base1: def f1(self): print('f1 in Base1') def f2(self): print('f2 in Base1') class Base2: def f1(self): print('f2 in Base2') def f2(self): print('f2 in Base2') def f3(self): print('f3 in Base2') self.f1() class Fool(Base1,Base2): def f0(self): print('f0 in Fool') self.f3() Foolobj = Fool() Foolobj.f0() ''' f0 in Fool f3 in Base2 f1 in Base1 ''' 小作业 '''将如下函数改成类''' def login(): user = input('输入用户名') pwd = input('输入密码') if user == 'negu' and pwd == 'geniue': print('login successfully') else: print('Failed') #改成类 class Acount: def login(self): user = input('输入用户名') pwd = input('输入密码') if user == 'negu' and pwd == 'geniue': print('login successfully') else: print('Failed') obj = Acount() obj.login()