第三模块:面向对象&网络编程基础 第1章 面向对象

时间:2021-03-20 22:28:42
  • 我的失败与梦想(一)
  • 我的失败与梦想之为何创办路飞学城
  • 01-编程范式
  • 02-面向过程编程
  • 03-面向对象编程介绍
  • 04-定义类与实例化出对象
  • 05-如何使用类
  • 06-如何使用对象
  • 07-属性查找与绑定方法
  • 08-Python中一切皆对象
  • 09-面向对象可拓展性总结
  • 10-小练习1
  • 11-小练习2
  • 12-继承与重用性
  • 13-派生
  • 14-继承的实现原理
  • 15-在子类中重用父类的方法或属性
  • 16-组合
  • 17-抽象类与归一化
  • 18-多态与多态性
  • 19-封装之如何隐藏属性
  • 20-封装的意义
  • 21-封装与可拓展性
  • 22-Property的使用
  • 23-绑定与非绑定方法介绍
  • 24-绑定方法与非绑定方法的使用
  • 25-反射
  • 26-内置方法介绍
  • 27-元类介绍
  • 28-自定义元类控制类的创建
  • 29-自定义元类与控制类的实例化行为
  • 30-自定义元类与控制类的实例化行为的应用
  • 31-面向对象的软件开发与作业介绍
  • 32-什么是异常处理
  • 33-try...except...详细用法

我的失败与梦想(一)

我的失败与梦想之为何创办路飞学城

01-编程范式

1、什么是面向对象编程?!编程范式

  • 数据结构:字符串、整型、列表、元组、字典、集合等,用来高效地存储数据;
  • 算法:编写程序的逻辑或者解决问题的流程;
  • 编程范式:武林中的各种流派;一大是面向过程,另一大是面向对象;

第三模块:面向对象&网络编程基础 第1章 面向对象

02-面向过程编程

1、面向过程编程;

核心是过程二字,过程是指解决问题IDE步骤,即设计一条流水线;机械式的思维方式;

  • 优点:把复杂的问题流程化,进而简单化;
  • 缺点:可拓展性比较差,应用场景:扬长避短,系统监控脚本,系统部署脚本,即需求变动不大的场景;
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/12 0012 5:21
#需求,写一个网站用户注册功能;使用面向过程的编程范式;
import json,re def interactive(): name = input('>>:').strip() passwd = input('>>:').strip() #拓展需求; email = input('>>:').strip() return { 'name':name, 'passwd':passwd, 'email':email, } def check(user_info): is_valid = True if len(user_info['name']) == 0: print('用户名不能为空。') is_valid = False if len(user_info['passwd']) < 6: print('密码不能少于6位。') is_valid = False # 拓展需求; if not re.search(r'@.*7\.com$',user_info['email']): print('邮箱格式不合法。') is_valid = False return { 'is_valid':is_valid, 'user_info':user_info, } def register(check_info): if check_info['is_valid']: with open(file='db.json',mode='w',encoding='utf-8') as f: json.dump(check_info['user_info'],f) #定义主函数main() def main(): user_info = interactive() check_info = check(user_info) register(check_info) if __name__ == '__main__': main()

03-面向对象编程介绍

1、面向对象:特征与技能的结合体,比如孙悟空:毛脸雷公嘴,七十二变化,金箍棒等;

  • 优点:是面向过程的缺点,即可拓展性强;
  • 缺点:是面向过程的优点,编程复杂性高;
  • 应用场景:用户需求经常变化,比如和互联网应用、游戏、企业内部应用,比如OA、ERP;

第三模块:面向对象&网络编程基础 第1章 面向对象

04-定义类与实例化出对象

1、类的定义:即一系列对象相似的特征与技能的结合体;

强调:站在不同的角度,得到的分类是不一样的,比如站在实体的角度,人和铅笔、计算机是一类;站在生物的角度,以上就不是相同的一类;

2、先有类还是先有对象?!

  • 在现实世界中:先有对象,后总结出类,比如人类,猪类、狗类;
  • 在程序中:一定得先定义类,后调用类来产生对象;

3、站在路飞学城的角度,大家都是学生;

  • 在现实世界中:对象1、2、3;
  • 总结现实中路飞学城的学生类:1、相似的特征;2、相似的技能;

 4、定义类的方式;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/12 0012 5:47
""
"""
1、将对象进行分类,比如PC、笔记本;
"""
#先定义类;
class LuffyStudent:#类名首字母大写;
    school = 'luffycity'
    def learn(self):
        print('is learning.')
    def eat(self):
        print('is eating.')
    def sleep(self):
        print('is sleeping.')
#后产生对象;
student1 = LuffyStudent()
student2 = LuffyStudent()
student3 = LuffyStudent()

print(student1)#<__main__.LuffyStudent object at 0x000001E494370B00>
print(student2)#<__main__.LuffyStudent object at 0x000001E494370B38>
print(student3)#<__main__.LuffyStudent object at 0x000001E494370AC8>

第三模块:面向对象&网络编程基础 第1章 面向对象

第三模块:面向对象&网络编程基础 第1章 面向对象

05-如何使用类

1、类的增删改查;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/12 0012 6:05
#先定义类;
class LuffyStudent:#类名首字母大写;
    school = 'luffycity'#特征,以变量的形式定义;
    def learn(self):#技能1,以函数的形式定义;
        print('is learning.')
    def eat(self):#技能2,以函数的形式定义;
        print('is eating.')
    def sleep(self):#技能3,以函数的形式定义;
        print('is sleeping.')
#查看类的名称空间;
print(LuffyStudent.__dict__)#{'__module__': '__main__', 'school': 'luffycity', 'learn': <function LuffyStudent.learn at 0x000001A59EE71AE8>, 'eat': <function LuffyStudent.eat at 0x000001A59EE71EA0>, 'sleep': <function LuffyStudent.sleep at 0x000001A59EE71B70>, '__dict__': <attribute '__dict__' of 'LuffyStudent' objects>, '__weakref__': <attribute '__weakref__' of 'LuffyStudent' objects>, '__doc__': None}
print(LuffyStudent.__dict__['school'])#luffycity
print(LuffyStudent.__dict__['learn'])#<function LuffyStudent.learn at 0x0000021C5B221AE8>
"""
类内部定义的变量称之为:数据属性;
类内部定义的函数称之为:函数属性;

"""
#import time
#time.sleep(1)
#查看;
print(LuffyStudent.school)#luffycity
print(LuffyStudent.learn)#<function LuffyStudent.learn at 0x000002A0CD0B1AE8>
#增加;
LuffyStudent.country = 'China'
#print(LuffyStudent.__dict__)
#使用专门的语法进行;
print(LuffyStudent.country)#China

#删除;
del LuffyStudent.country
print(LuffyStudent.__dict__)#发现country已经被删除;
#print(LuffyStudent.country)#AttributeError: type object 'LuffyStudent' has no attribute 'country'

#改;
LuffyStudent.school = 'Luffycity'
print(LuffyStudent.school)#Luffycity

"""
小结:
1、函数名加(),执行函数;
2、类名加(),实例化得到一个对象;
3、类的用途:对类属性的操作——增删改查;实例化产生出对象;
"""

06-如何使用对象

1、对象的增删改查操作;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/12 0012 6:41
#__init__方法,用来为对象定制对象自己独有的特征;
#先定义类;
class LuffyStudent:#类名首字母大写;
    school = 'luffycity'
    #student1,'王二丫','女',18
    def __init__(self,name,sex,age):
        self.Name = name
        self.Sex = sex
        self.Age = age
        #student1.Name='王二丫'
        #student2.Sex='女'
        #student3.Age=18
    def learn(self):
        print('is learning.')
    def eat(self):
        print('is eating.')
    def sleep(self):
        print('is sleeping.')
#后产生对象;
#student1 = LuffyStudent()#TypeError: __init__() missing 3 required positional arguments: 'name', 'sex', and 'age'
#Python会自动调用__init对象;
student1 = LuffyStudent('王二丫','',18)
#加上__init__方法后,实例化的步骤;
"""
1、先产生一个空对象student1;
2、LuffyStudent.__init__(student1,'王二丫','女',18)
"""
#查询;
print(student1.__dict__)#{'Name': '王二丫', 'Sex': '女', 'Age': 18}
print(student1.Name)#王二丫
print(student1.Age)#18
print(student1.Sex)#
#
student1.Name = '李静瓶'
print(student1.__dict__)#{'Name': '李静瓶', 'Sex': '女', 'Age': 18}
print(student1.Name)#李静瓶
#删除
del student1.Name
print(student1.__dict__)
#增加
student1.Course = 'Python全栈开发'#{'Sex': '女', 'Age': 18, 'class_name': 'Python全栈开发'}
print(student1.__dict__)

#student2操作
student2 = LuffyStudent('李三炮','',38)
print(student2.__dict__)#{'Name': '李三炮', 'Sex': '男', 'Age': 38}
print(student2.Name)
print(student2.Age)
print(student2.Sex)

07-属性查找与绑定方法

1、绑定方法与属性查找;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/12 0012 7:04
#先定义类;
class LuffyStudent:#类名首字母大写;
    school = 'luffycity'
    #student1,'王二丫','女',18
    def __init__(self,name,sex,age):
        self.Name = name
        self.Sex = sex
        self.Age = age
        #student1.Name='王二丫'
        #student2.Sex='女'
        #student3.Age=18
    def learn(self):
        #print('is learning.')
        print('%s is learning'%self.Name)
    def eat(self):
        print('is eating.')
    def sleep(self):
        print('is sleeping.')
#后产生对象;
#student1 = LuffyStudent()#TypeError: __init__() missing 3 required positional arguments: 'name', 'sex', and 'age'
#Python会自动调用__init对象;
student1 = LuffyStudent('王二丫','',18)
student2 = LuffyStudent('李三炮','',38)
student3 = LuffyStudent('张铁蛋','',48)
print(student1.__dict__)
print(student2.__dict__)
print(student3.__dict__)
""
{'Name': '王二丫', 'Sex': '', 'Age': 18}
{'Name': '李三炮', 'Sex': '', 'Age': 38}
{'Name': '张铁蛋', 'Sex': '', 'Age': 48}
""
#对象:特征与技能的结合体,比如孙悟空这个角色;
#类:类是一系列对象相似的特征与相似的技能的结合体;


#类中的数据属性:是所有的对象公共的;
print(LuffyStudent.school)
print(student1.school,id(student1.school))
print(student2.school,id(student2.school))
print(student3.school,id(student3.school))
"""
luffycity
luffycity 2904853177648
luffycity 2904853177648
luffycity 2904853177648
"""
#类中的函数属性:是绑定给对象使用的,绑定到不同的对象是不同的绑定方法;
#对象调用绑定方法时候,会把对象本身,当做第一个函数传入,传给self
print(LuffyStudent.learn)
print(student1.learn)
print(student2.learn)
print(student3.learn)
"""
<function LuffyStudent.learn at 0x00000234A0FC1B70>
<bound method LuffyStudent.learn of <__main__.LuffyStudent object at 0x00000234A0FC5C88>>
<bound method LuffyStudent.learn of <__main__.LuffyStudent object at 0x00000234A0FC5CC0>>
<bound method LuffyStudent.learn of <__main__.LuffyStudent object at 0x00000234A0FC5CF8>>
"""
#LuffyStudent.learn()#TypeError: learn() missing 1 required positional argument: 'self'
LuffyStudent.learn(student1)#王二丫 is learning
student1.learn()#王二丫 is learning
"""
小结:
1、类中定义的函数是给对象使用的,绑定给对象使用,不同的对象具备相同的技能,但内存地址不一致;
"""
student1.x = 'from student1'#给对象增加一个属性;
LuffyStudent.x = 'from LuffyCity class '
print(student1.__dict__)#{'Name': '王二丫', 'Sex': '女', 'Age': 18, 'x': 'from student1'}
print(student1.x)#from student1

第三模块:面向对象&网络编程基础 第1章 面向对象

08-Python中一切皆对象

1、一切皆对象的解释说明;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/12 0012 7:30
""
"""
小结:
1、站的角度不同,定义出的类是截然不同的;
2、现实生活中的类不完全等于程序中的类,比如现实中的公司类,在程序中有时需要拆分成部门类、业务类等;
3、有时候为了编程需求,程序中也有可能会定义现实中不存在的类,比如策略类,现实中并不存在,但是在程序中却是一个很常见的类;
补充:
1、Python当中一切皆对象,Python3.x中统一了类与数据类型的概念;
"""
#先定义类;
class LuffyStudent:#类名首字母大写;
    school = 'luffycity'
    #student1,'王二丫','女',18
    def __init__(self,name,sex,age):
        self.Name = name
        self.Sex = sex
        self.Age = age
        #student1.Name='王二丫'
        #student2.Sex='女'
        #student3.Age=18
    def learn(self):
        #print('is learning.')
        print('%s is learning'%self.Name)
    def eat(self):
        print('is eating.')
    def sleep(self):
        print('is sleeping.')
print(LuffyStudent)
print(list)
"""
<class '__main__.LuffyStudent'>
<class 'list'>
"""
l1 = [1,2,3]#等价于,l1 = list([1,2,3])
l2 =[]#等价于,l2 = list([1,2,3])
#列表的内置方法;
l1.append(4)
print(l1)#[1, 2, 3, 4]
print(l2)#[]
list.append(l1,4)#虽然可以实现功能,但是没人这么用,我们都是使用对象的绑定方法;比如l1.append()
print(l1)#[1, 2, 3, 4, 4],效果等价于l1.append(4)

09-面向对象可拓展性总结

 1、面向对象拓展性总结;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/12 0012 7:40
""
class Chinese:
    country = 'China'
    def __init__(self,name,sex,age):
        self.Name = name
        self.Sex = sex
        self.Age = age
        #student1.Name='王二丫'
        #student2.Sex='女'
        #student3.Age=18
    def learn(self):
        #print('is learning.')
        print('%s is learning'%self.Name)
    def eat(self):
        print('%s is eating.'%self.Name)
p1 = Chinese('egon',18,'male')
p2 = Chinese('alex',38,'female')
p3 = Chinese('wqp',48,'female')
print(p1.country)#china
print(p2.country)#china
print(p3.country)#china

p1.eat()
p2.eat()
p3.eat()
"""
egon is eating.
alex is eating.
wqp is eating.
"""

 

从代码级别看面向对象
1、在没有学习类这个概念时,数据与功能是分离的

def exc1(host,port,db,charset):
    conn=connect(host,port,db,charset)
    conn.execute(sql)
    return xxx


def exc2(host,port,db,charset,proc_name)
    conn=connect(host,port,db,charset)
    conn.call_proc(sql)
    return xxx

#每次调用都需要重复传入一堆参数
exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;')
exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字')
2、我们能想到的解决方法是,把这些变量都定义成全局变量

HOST=‘127.0.0.1’
PORT=3306
DB=‘db1’
CHARSET=‘utf8’

def exc1(host,port,db,charset):
    conn=connect(host,port,db,charset)
    conn.execute(sql)
    return xxx


def exc2(host,port,db,charset,proc_name)
    conn=connect(host,port,db,charset)
    conn.call_proc(sql)
    return xxx

exc1(HOST,PORT,DB,CHARSET,'select * from tb1;')
exc2(HOST,PORT,DB,CHARSET,'存储过程的名字')
3、但是2的解决方法也是有问题的,按照2的思路,我们将会定义一大堆全局变量,这些全局变量并没有做任何区分,即能够被所有功能使用,然而事实上只有HOST,PORT,DB,CHARSET是给exc1和exc2这两个功能用的。言外之意:我们必须找出一种能够将数据与操作数据的方法组合到一起的解决方法,这就是我们说的类了

class MySQLHandler:
    def __init__(self,host,port,db,charset='utf8'):
        self.host=host
        self.port=port
        self.db=db
        self.charset=charset
        self.conn=connect(self.host,self.port,self.db,self.charset)
    def exc1(self,sql):
        return self.conn.execute(sql)

    def exc2(self,sql):
        return self.conn.call_proc(sql)


obj=MySQLHandler('127.0.0.1',3306,'db1')
obj.exc1('select * from tb1;')
obj.exc2('存储过程的名字')
总结使用类可以:

 将数据与专门操作该数据的功能整合到一起。
可扩展性高
定义类并产生三个对象

class Chinese:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex


p1=Chinese('egon',18,'male')
p2=Chinese('alex',38,'female')
p3=Chinese('wpq',48,'female')
如果我们新增一个类属性,将会立刻反映给所有对象,而对象却无需修改

class Chinese:
    country='China'
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def tell_info(self):
        info='''
        国籍:%s
        姓名:%s
        年龄:%s
        性别:%s
        ''' %(self.country,self.name,self.age,self.sex)
        print(info)


p1=Chinese('egon',18,'male')
p2=Chinese('alex',38,'female')
p3=Chinese('wpq',48,'female')

print(p1.country)
p1.tell_info()

 

第三模块:面向对象&网络编程基础 第1章 面向对象

10-小练习1

1、练习No.01;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/12 0012 21:03
""
"""
1、练习1:编写一个学生类,产生一堆学生对象;
要求:
有一个计算器(属性),统计总共实例化了多少个对象。count方法统计;
"""
class Student:#定义一个Student类名;
    school = 'luffycity'
    count = 0#定义计数器变量count
    def __init__(self,name,age,sex):
        self.Name = name
        self.Age = age
        self.Sex = sex
        #self.Come = come
        Student.count +=1#每调用一次,自增1
        #self.count = self.count+1
    def learn(self):
        print('%s is learning'%self.name)
#实例化;
stu1=Student('alex','male',38)
stu2=Student('jinxing','female',78)
stu3=Student('egon','male',18)

print(Student.count)
print(stu1.count)
print(stu2.count)
print(stu3.count)

print(stu1.__dict__)
print(stu2.__dict__)
print(stu3.__dict__)
"""
3
3
3
3
{'Name': 'alex', 'Age': 'male', 'Sex': 38}
{'Name': 'jinxing', 'Age': 'female', 'Sex': 78}
{'Name': 'egon', 'Age': 'male', 'Sex': 18}
"""

11-小练习2

1、练习No.02;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/12 0012 21:20
""
"""
1、练习2:模仿LOL定义两个英雄类;
要求:
1、英雄需要有昵称、攻击力、生命值等属性;
2、实例化出两个英雄对象;
3、英雄之间可以互殴,被殴打的一方开始掉血,血量小于0则判定为死亡;
"""
#定义LOL中英雄的名称;
class Garen:
    camp = 'Demacia'#德玛西亚;
    def __init__(self,nickname,life_value,aggresivity):
        self.nickname = nickname
        self.life_value = life_value
        self.aggresivity = aggresivity
    def attact(self,enemy):
        enemy.life_value -= self.aggresivity

class Riven:
    camp = 'Noxus'#xxxx;
    def __init__(self,nickname,life_value,aggresivity):
        self.nickname = nickname
        self.life_value = life_value
        self.aggresivity = aggresivity
    def attact(self,enemy):
        enemy.life_value -= self.aggresivity
g1=Garen('草丛伦',100,30)
r1 = Riven('可爱的芮雯雯',80,50)
#打印初始生命值;
print(r1.life_value)#80
g1.attact(r1)
#打印被攻击一次后的生命值;
print(r1.life_value)#50

12-继承与重用性

 

# #!/usr/bin/env python
# # -*- coding:utf-8 -*-
# # __Author__:Administrator
# # Version:python3.6.5
# # Date:2018/6/12 0012 21:38
# #定义一个父类1;
# class ParentClass1:
#     pass
# #定义一个父类2;
# class ParentClass2:
#     pass
# #定义一个子类1;
# class SubClass1(ParentClass1):
#     pass
# #定义一个子类2;同时继承两个父类;
# class SubClass2(ParentClass1,ParentClass2):
#     pass
# print(SubClass1.__bases__)#(<class '__main__.ParentClass1'>,)
# print(SubClass2.__bases__)#(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
#
class Hero:#定义一个英雄类;
    x = 3
    def __init__(self,nickname,life_value,aggresivity):#属性;
        self.nickname = nickname
        self.life_value = life_value
        self.aggresivity = aggresivity
    def attact(self,enemy):#攻击技能;
        enemy.life_value -= self.aggresivity

class Garen(Hero):
    #x = 2
    pass#德玛西亚;
class Riven(Hero):
    pass
g1=Garen('刚们',29,30)
print(g1.nickname,g1.life_value,g1.aggresivity)#刚们 29 30
#继承,实现代码的重用性!
#那么问题来了,属性的查找顺序是怎样的?
#g1.x =1
print(g1.x)

#属性查找的小练习;
class Foo:
    def f1(self):
        print('from Foo.f1')
    def f2(self):
        print('from Foo.f2')
        self.f1()#b.f1(),注意查找顺序,从下往上查找;
class Bar(Foo):
    def f1(self):
        print('from Bar.f1')
b = Bar()
print(b.__dict__)
b.f2()
b.f1()#注意查找顺序;
"""
from Bar.f1
from Bar.f1
"""

第三模块:面向对象&网络编程基础 第1章 面向对象

13-派生

1、派生的概念引入;

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# __Author__:Administrator
# Version:python3.6.5
# Date:2018/6/12 0012 22:17
#派生的概念引入;
class Hero:#定义一个英雄类;
    def __init__(self,nickname,life_value,aggresivity):#属性;
        self.nickname = nickname
        self.life_value = life_value
        self.aggresivity = aggresivity
    def attact(self,enemy):#攻击技能;
        enemy.life_value -= self.aggresivity

class Garen(Hero):
    camp ='Demacia'#德玛西亚;
class Riven(Hero):
    camp = 'Noxus'
g = Garen('草丛伦',100,30)
r = Riven('锐雯雯',80,50)
print(g.camp)#Demacia
g.attact(r)
print(r.life_value)#50

14-继承的实现原理

15-在子类中重用父类的方法或属性

16-组合

17-抽象类与归一化

18-多态与多态性

19-封装之如何隐藏属性

20-封装的意义

21-封装与可拓展性

22-Property的使用

23-绑定与非绑定方法介绍

24-绑定方法与非绑定方法的使用

25-反射

26-内置方法介绍

27-元类介绍

28-自定义元类控制类的创建

29-自定义元类与控制类的实例化行为

30-自定义元类与控制类的实例化行为的应用

31-面向对象的软件开发与作业介绍

32-什么是异常处理

33-try...except...详细用法