一、创建类和对象

面向对象是一种编程方式,此编程方式的实现是基于对  和 对象 的使用

类是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中)

对象,根据模板创建的实例(即:对象),实例用于调用被包装在类中的函数

  1. def Dog(name,type):
  2.  
  3. def call(dog):
  4.  
  5. print("这是一条%s,名字叫%s"%(dog['type'],dog['name']))
  6.  
  7. def eat(dog):
  8.  
  9. print("%s正在啃骨头"%dog['type'])
  10.  
  11. def init(name,type):
  12.  
  13. dog_dcit={'name':name,'type':type,'call':call,'eat':eat}
  14.  
  15. return dog_dcit
  16.  
  17. res=init(name,type)
  18.  
  19. return res
  20.  
  21. d1=Dog('小狗',"中华田园犬")
  22.  
  23. d1['call'](d1)
  24. d1['eat'](d1)

面向对象设计

类的成员可以分为三大类:字段(类变量)、方法(动态属性)和属性(静态属性)

1、类的语法

在python3.0 中有两种写法,一种是经典类还有一种是新式类

经典类和新式类的区别:继承方法上的区别,分为广度优先和深度优先两种继承策略

  1. class Dog: #经典类,类名后不加括号
  2.  
  3. def __init__(self,name): #构造函数
  4.  
  5. self.name=name
  6.  
  7. def bulk(self):
  8. print('%s,汪汪'%self.name)
  9.  
  10. d1 = Dog("小红") #初始化一个类 构造一个对象 self相当于d1 Dog(d1,"小红")
  11. d2 = Dog("小明")
  12.  
  13. d1.bulk()
  14. d2.bulk()

经典类

  1. class Dog(object): #新式类,类名后加括号(object)
  2.  
  3. def __init__(self,name): #构造函数
  4.  
  5. self.name=name
  6.  
  7. def bulk(self):
  8. print('%s,汪汪'%self.name)
  9.  
  10. d1 = Dog("小红") #初始化一个类 构造一个对象 self相当于d1 Dog(d1,"小红")
  11. d2 = Dog("小明")
  12.  
  13. d1.bulk()

新式类

2、类变量、方法和属性

类变量:在类中定义的变量class Role(object): #定义类

  1. num=123 #类变量,大家都可以调用
  2. num_list=[]
  3.  
  4. def __init__(self, name, role, weapon, life_value=100, money=15000): #构造函数 在实例化时做一些类的初始化的工作
  5.  
  6. self.name = name #self.name 赋给实例 实例变量(静态属性) 作用域就是实例本身
  7. self.role = role
  8. self.weapon = weapon
  9. self.__life_value = life_value #私有属性前面要加两个下划线__来定义,私有属性只可以在方法里面调用
  10. self.money = money
  11.  
  12. def __del__(self): #析构函数 实例或者对象消亡或者程序结束时才调用
  13. #在实例释放或销毁的时候自动执行,通常用于做一些收尾工作
  14. #如:关闭一些数据库连接,打开的临时文件
  15. print("%s 彻底死了。。。。"%self.name)
  16.  
  17. def shot(self):
  18. print("shooting...")
  19.  
  20. def got_shot(self): #定义类的方法(功能)也叫作动态属性
  21. print("ah...,I got shot...")
  22.  
  23. def buy_gun(self,gun_name):
  24. print("%s just bought %s" %(self.name,gun_name)) #方法里的self self.name 相当于r1.name
  25.  
  26. def show_life(self):
  27.  
  28. print("life %s"%self.__life_value) #私有属性 只可以在内部方法里调用
  29.  
  30. def __get_weapon(self): #定义私有方法 在定义方法名前加两个下划线,私有方法也是只能在类方法中被调用
  31. print('私有方法')
  32.  
  33. Role_dict=Role.__dict__ # 查看类的属性字典
  34.  
  35. print(Role_dict)
  36. #输出:{'__module__': '__main__', 'num': 123, 'num_list': [], '__init__': <function Role.__init__ at 0x10ed6c290>, '__del__': <function Role.__del__ at 0x10ed6c320>, 'shot': <function Role.shot at 0x10ed6c710>, 'got_shot': <function Role.got_shot at 0x10ed6c7a0>, 'buy_gun': <function Role.buy_gun at 0x10ed6c830>, '_Role__get_weapon': <function Role.__get_weapon at 0x10ed6c8c0>, 'show_life': <function Role.show_life at 0x10ed6c950>, '__dict__': <attribute '__dict__' of 'Role' objects>, '__weakref__': <attribute '__weakref__' of 'Role' objects>, '__doc__': None}
  37.  
  38. r1 = Role('Alex', 'police', 'AK47') # 生成一个角色 (初始化一个类,造了一个对象) 把一个类变成一个具体对象的过程叫实列化
    # Role(r1,'Alex','police','AK47') r1.name=name 是这样实例的
    #Role(r1,'Alex','police','AK47') self.name 相当于 r1.name
  39.  
  40. # print(r1.__dict__) #查看实例的属性字典
    #输出:{'name': 'Alex', 'role': 'police', 'weapon': 'AK47', '_Role__life_value': 100, 'money': 15000}
  41.  
  42. r2 = Role('Jack', 'terrorist', 'B22') # 生成一个角色
  43. r1.buy_gun('AK-47')
  44. r2.buy_gun('加特林')
  45.  
  46. r1.n=456
  47. print(r1.n) #输出是456 互不影响
  48.  
  49. r3=Role('lucy','artist','AK47')
  50. print(r3.n) #输出是123 在实例r1中值被修改 但是在实例r3中不影响,互相独立 只是类在实例化对象时 都独自开辟了一块内存
  51.  
  52. Role.n=789
  53. print(r1.n,r3.n) #输出 r1.n是456不是789 因为r1.n已经被实例化过r3.n是789

3、类属性的增删查改

  1. class Chinese:
  2.  
  3. country="China"
  4.  
  5. def __init__(self,name):
  6.  
  7. self.name=name
  8.  
  9. def play_ball(self,ball):
  10.  
  11. print("%s 正在打 %s"%(self.name))
  12.  
  13. def sayWord(self,word):
  14. print("%s 说 %s"%(self.name,word))
  15.  
  16. # 查看类的属性
  17. print(Chinese.country)
  18.  
  19. # 修改类的属性
  20. Chinese.country ="Japan"
  21. p1=Chinese("allen")
  22.  
  23. print(Chinese.country,p1.country)
  24.  
  25. # 删除类的属性
  26. # del Chinese.country
  27. # print(Chinese.country) # 会报错
  28.  
  29. # 增加类的属性
  30. Chinese.language = "汉语"
  31. p2=Chinese("lucy")
  32. print(Chinese.country,p2.country,p2.language)
  33. print(Chinese.__dict__)
  34.  
  35. # 函数属性的增删改查
  36.  
  37. def learning(self,course):
  38.  
  39. print("%s is learning %s"%(self.name,course))
  40.  
  41. Chinese.learn=learning
  42.  
  43. p3=Chinese("Lily")
  44.  
  45. p3.learn("france")

类属性的增删改查

  1. class Chinese:
  2.  
  3. country="China"
  4.  
  5. def __init__(self,name):
  6.  
  7. self.name=name
  8.  
  9. def play_ball(self,ball):
  10.  
  11. print("%s 正在打 %s"%(self.name,ball))
  12.  
  13. def sayWord(self,word):
  14. print("%s 说 %s"%(self.name,word))
  15.  
  16. # 查看实例的属性
  17. p1=Chinese("allen")
  18. print(p1.name)
  19. print(p1.play_ball)
  20.  
  21. # 增加实例的属性
  22. p1.age = 18
  23. print(p1.__dict__)
  24.  
  25. # 修改实例的属性
  26. p1.age = 19
  27.  
  28. print(p1.__dict__)

实例属性的增删改查

4、类的组合

  1. class Head:
  2. pass
  3.  
  4. class Foot:
  5. pass
  6.  
  7. class Body:
  8. pass
  9.  
  10. class Person:
  11. def __init__(self,id_num,name):
  12.  
  13. self.id_num=id_num
  14. self.name=name
  15. self.head=Head() # 实例化一个Head类
  16. self.body=Body() # 实例化一个Body类
  17. self.foot=Foot() # 实例化一个Foot类
  18.  
  19. p=Person("","allen")
  20.  
  21. print(p.__dict__)

组合

  1. class School:
  2. def __init__(self,name,address):
  3.  
  4. self.name=name
  5. self.address=address
  6.  
  7. def academy(self):
  8. print("%s学校的地址是%s"%(self.name,self.address))
  9.  
  10. class Course:
  11. def __init__(self,course_name,school):
  12. self.course_name=course_name
  13.  
  14. self.school=school
  15.  
  16. s1=School("山东大学","济南")
  17. s2=School("北京大学","北京")
  18. s3=School("深圳大学","深圳")
  19.  
  20. msg="""
  21. 1.山东大学
  22. 2.北京大学
  23. 3.深圳大学
  24. """
  25.  
  26. while True:
  27. print(msg)
  28. schoolInfo={"":s1,"":s2,"":s3}
  29. choice=input("请选择学校:")
  30. courseName=input("请输入课程名:")
  31. c1=Course(courseName,schoolInfo[choice])
  32.  
  33. print("课程%s属于%s"%(c1.course_name,c1.school.name))

示例-选课系统

二、面向对象三大特性

面向对象三大特性:封装、继承和多态

1、继承

继承概念的实现方式主要有2类:实现继承、接口继承。

Ø         实现继承是指使用基类的属性和方法而无需额外编码的能力;
Ø         接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力(子类重构爹类方法);
在python2中 经典类是按深度优先来继承的 新式类是按广度优先来继承的;在python3中 经典类和新式类都是按广度优先来继承的。
  1. class A(object): #基类
  2. def __init__(self):
  3. print("A")
  4.  
  5. class B(A):
  6. # def __init__(self): # B继承A 单继承
  7. # print("B")
  8. pass
  9.  
  10. class C(A):
  11. # def __init__(self): # C继承A
  12. # print("C")
  13. pass
  14.  
  15. class D(B,C):
  16. #def __init__(self): #D继承B和C 多继承
  17. # print("D")
  18. pass
  19.  
  20. a=D()

继承

子类继承了父类的所有属性。子类自定义的属性如果和父类的属性重名了,那就直接调用自己的属性,不再调用父类的属性。

1.1、继承顺序

Python2中的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先

  • 当类是经典类时,多继承情况下,会按照深度优先方式查找
  • 当类是新式类时,多继承情况下,会按照广度优先方式查找

Python3中统一都是新式类,都是广度优先查找。

  1. class A(object):
  2. def test(self):
  3. print('from A')
  4.  
  5. class B(A):
  6. def test(self):
  7. print('from B')
  8.  
  9. class C(A):
  10. def test(self):
  11. print('from C')
  12.  
  13. class D(B):
  14. # def test(self):
  15. # print('from D')
  16. pass
  17.  
  18. class E(C):
  19. def test(self):
  20. print('from E')
  21.  
  22. class F(D,E):
  23. # def test(self):
  24. # print('from F')
  25. pass
  26. f1=F()
  27. f1.test()
  28.  
  29. # 查找顺序:F --> D --> B --> E --> C --> A

python3新式类广度优先继承

python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表。

例如:

  1. print(F.__mro__) #打印mro列表
  2.  
  3. [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

 1.2、子类中调用父类的方法 

  1. class People(object):
  2. def __init__(self, name, age):
  3. self.name = name
  4. self.age = age
  5.  
  6. def eat(self):
  7. print("%s is eating" % self.name)
  8.  
  9. def sleep(self):
  10. print("%s is sleeping" % self.name)
  11.  
  12. def print_tab(self):
  13. print("%s 今年 %s" % (self.name, self.age))
  14.  
  15. class Relation(object):
  16.  
  17. def make_friend(self, obj):
  18. print("%s is making friends with %s" % (self.name, obj.name))
  19.  
  20. class Man(Relation, People): # 继承Relation,和People两个基类
  21.  
  22. def __init__(self, name, age, money):
  23. People.__init__(self, name, age) # 重构经典类写法
  24. # super(Man,self).__init__(name,age) # 新式写法
  25. self.money = money
  26.  
  27. def drink(self):
  28. print("%s is drinking %s" % (self.name, self.money))
  29.  
  30. def sleep(self): # 基类中也有sleep()方法
  31. People.sleep(self) # 重构基类中sleep()方法后 先调用基类的sleep()方法 再调用自己的方法 如果不重构,就调用自己的sleep()方法
  32. print("man is sleeping")
  33.  
  34. class Women(People, Relation): # 继承Relation,和People两个基类
  35.  
  36. def get_birth(self):
  37. print("%s is making face" % self.name)
  38.  
  39. m1 = Man("Jim", 20, 100)
  40. m1.drink()
  41. m1.sleep()
  42. m1.eat()
  43. w1 = Women("lucy", 20)
  44. w1.get_birth()
  45.  
  46. m1.make_friend(w1)
  1. # -*-coding:utf-8-*-
  2.  
  3. class school(object):
  4.  
  5. def __init__(self,name,addr):
  6. self.name=name
  7. self.addr=addr
  8. self.students=[]
  9. self.teachers=[]
  10.  
  11. def enroll(self,stu_obj):
  12. print('为%s学员办理注册手续'%stu_obj.name)
  13. self.students.append(stu_obj)
  14.  
  15. class SchoolMember(object):
  16. def __init__(self,name,age,sex):
  17. self.name=name
  18. self.age=age
  19. self.sex=sex
  20.  
  21. class Teacher(SchoolMember):
  22.  
  23. def __init__(self,name,age,sex,salary,course):
  24. super(Teacher,self).__init__(name,age,sex)
  25. self.salary=salary
  26. self.course=course
  27.  
  28. def tell(self):
  29. print("""-------info of Teacher:---------
  30. name:%s
  31. age:%s
  32. sex:%s
  33. salary:%s
  34. course=%s
  35. """ % (self.name, self.age, self.sex, self.salary, self.course))
  36.  
  37. def teach(self):
  38. print("%s is teaching course[%s]"%(self.name,self.course))
  39.  
  40. class Student(SchoolMember):
  41.  
  42. def __init__(self,name,age,sex,stu_id,grade):
  43. super(Student,self).__init__(name,age,sex)
  44. self.stu_id=stu_id
  45. self.grade=grade
  46.  
  47. def tell(self):
  48. print("""-------info of student:---------
  49. name:%s
  50. age:%s
  51. sex:%s
  52. stu_id:%s
  53. grade=%s
  54. """ % (self.name, self.age, self.sex, self.stu_id, self.grade))
  55.  
  56. def pay(self,account):
  57. print("%s paid account:$%d"%(self.name,account))
  58.  
  59. school1=school('北京大学','北京')
  60.  
  61. teacher1=Teacher('李老师',30,'男',5000,'Linux')
  62. teacher2=Teacher('陈老师',23,'女',3000,'PHP')
  63.  
  64. student1=Student('小明',23,'女',1001,'python')
  65. student2=Student('小露',25,'女',1002,'python')
  66.  
  67. teacher1.tell()
  68.  
  69. student1.tell()
  70.  
  71. school1.enroll(student1)
  72.  
  73. print(school1.students)
  74.  
  75. school1.students[0].pay(5000)

示例

2、多态

多态指的是一类事物有多种形态,指出了对象如何通过他们共同的属性和动作来操作及访问,而不需要考虑他们具体的类。

一种接口,多种实现 python 不直接支持多态,可以间接实现

  1. class Animal(object):
  2. def __init__(self, name): # Constructor of the class
  3. self.name = name
  4.  
  5. # def talk(self): # Abstract method, defined by convention only
  6. # raise NotImplementedError("Subclass must implement abstract method")
  7. @staticmethod
  8. def func(obj): # 一个接口,多种形态
  9. obj.talk()
  10.  
  11. class Cat(Animal):
  12. def talk(self):
  13. print('%s: 喵喵喵!' % self.name)
  14.  
  15. class Dog(Animal):
  16. def talk(self):
  17. print('%s: 汪!汪!汪!' % self.name)
  18.  
  19. c1 = Cat('小晴')
  20. d1 = Dog('李磊')
  21.  
  22. Animal.func(c1)
  23. Animal.func(d1)

多态

 3、封装

1、封装的特性:双下划线__开头(私有属性和私有方法),类内部可以调用,外部不可调用。

注意: 双下划线开头在外部不能被调用是因为被类重新命名了,其实在外部是可以被调用的。

  1. class Role:
  2. num = 123 # 类变量,大家都可以调用
  3. num_list = []
  4. __info="角色"
  5. def __init__(self, name, role, weapon, life_value=100, money=15000):
  6.  
  7. self.name = name # self.name 赋给实例 实例变量(静态属性) 作用域就是实例本身
  8. self.role = role
  9. self.weapon = weapon
  10. self.__life_value = life_value # 私有属性前面要加两个下划线__来定义,私有属性只可以在方法里面调用
  11. self.money = money
  12.  
  13. def shot(self):
  14. print("shooting...")
  15.  
  16. def got_shot(self):
  17. print("ah...,I got shot...",self.__info)
  18.  
  19. def __get_weapon(self): # 定义私有方法 在定义方法名前加两个下划线,私有方法也是只能在类方法中被调用
  20. print('私有方法',self.__info)
  21.  
  22. r=Role("Jim","武器","ak47")
  23. #print(r.__info) 这样是调用不到的,因为它被类重新命名为_Role__info了
  24. print(Role.__dict__)
  25. #双下划线开头在外部不能被调用是因为被类重命名了
  26. print(r._Role__info) # 私有属性这样就可以调用了
  27. r._Role__get_weapon() # 私有方法这样可以被调用

封装-私有属性和方法

Python全栈开发之6、面向对象的更多相关文章

  1. 战争热诚的python全栈开发之路

    从学习python开始,一直是自己摸索,但是时间不等人啊,所以自己为了节省时间,决定报个班系统学习,下面整理的文章都是自己学习后,认为重要的需要弄懂的知识点,做出链接,一方面是为了自己找的话方便,一方 ...

  2. python全栈开发之OS模块的总结

    OS模块 1. os.name()      获取当前的系统 2.os.getcwd      #获取当前的工作目录 import os cwd=os.getcwd() # dir=os.listdi ...

  3. Python全栈开发之14、Javascript

    一.简介 前面我们学习了html和css,但是我们写的网页不能动起来,如果我们需要网页出现各种效果,那么我们就要学习一门新的语言了,那就是JavaScript,JavaScript是世界上最流行的脚本 ...

  4. Python全栈开发之1、输入输出与流程控制

    Python简介 python是吉多·范罗苏姆发明的一种面向对象的脚本语言,可能有些人不知道面向对象和脚本具体是什么意思,但是对于一个初学者来说,现在并不需要明白.大家都知道,当下全栈工程师的概念很火 ...

  5. Python全栈开发之MySQL(二)------navicate和python操作MySQL

    一:Navicate的安装 1.什么是navicate? Navicat是一套快速.可靠并价格相宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设.它的设计符合数据库管理员.开发人员及中小 ...

  6. Python全栈开发之9、面向对象、元类以及单例

    前面一系列博文讲解的都是面向过程的编程,如今是时候来一波面向对象的讲解了 一.简介 面向对象编程是一种编程方式,使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” ...

  7. Python全栈开发之7、面向对象编程进阶-类属性和方法、异常处理和反射

    一.类的属性 1.@property属性 作用就是通过@property把一个方法变成一个静态属性 class Room: def __init__(self,name,length,width,he ...

  8. python全栈开发之路

    一.Python基础 python简介 python数据类型(数字\字符串\列表) python数据类型(元组\字典) python数据类型(集合) python占位符%s,%d,%r,%f prin ...

  9. Python全栈开发之MySQL(三)视图,存储过程触发器,函数,事务,索引

    一:视图 1:什么是视图? 视图是指存储在数据库中的查询的SQL语句,具有简单.安全.逻辑数据独立性的作用及视点集中简化操作定制数据安全性的优点.视图包含一系列带有名称的列和行数据.但是,视图并不在数 ...

随机推荐

  1. javascript内置对象一: Array数组

    在JavaScript中的任何事物,字符串,数组,函数等等都是对象. 理解:浏览器自己封装好的对象,可以直接使用. push   /pʊʃ/  增加 在末尾增加              unshif ...

  2. [Python自学] day-20 (Django-ORM、Ajax)

    一.外键跨表操作(一对多) 在 [Python自学] day-19 (2) (Django-ORM) 中,我们利用外键实现了一对多的表操作. 可以利用以下方式来获取外键指向表的数据: def orm_ ...

  3. Codeforces Round #402 (Div. 2) D题 【字符串二分答案+暴力】

    D. String Game Little Nastya has a hobby, she likes to remove some letters from word, to obtain anot ...

  4. PHP mysqli_field_tell() 函数

    mysqli_field_tell() 函数返回字段指针的位置. 取得所有字段的字段信息,然后通过 mysqli_field_tell() 取得当前字段并输出字段名称.表格和最大长度: <?ph ...

  5. 2019CCPC秦皇岛自我反省&部分题解

    练了一年半了,第一次打CCPC,险些把队友坑了打铁,最后也是3题危险捡了块铜. 非常水的点双连通,我居然不相信自己去相信板子,唉,结果整来整去,本来半个小时能出的题,整到了3个小时,大失误呀,不然就可 ...

  6. Meathill的博客地址

    https://blog.meathill.com/ 安装mysql: https://blog.meathill.com/tech/setup-windows-subsystem-linux-for ...

  7. 论一种基于JS技术的WEB前端动态生成框图的方法

    前言 HTML是一种标记语言,由HTML的标签元素和文本编写的文档可被浏览器描述为一幅网页.通常情况下网页的实现是由HTML.CSS和Javascript三者结合完成的,HTML负责网页的结构,CSS ...

  8. LeetCode 229. 求众数 II(Majority Element II )

    题目描述 给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素. 说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1). 示例 1: 输入: [3,2,3] 输出: ...

  9. 前端知识点回顾之重点篇——ES6的async函数和module

    async函数 ES2017 标准引入了 async 函数,使得异步操作变得更加方便. async 函数是 Generator 函数的语法糖 什么是语法糖? 意指那些没有给计算机语言添加新功能,而只是 ...

  10. wait_timeout 和 interactive_timeout

    wait_timeout 和 interactive_timeout Table of Contents 1. 参数说明 2. 原代码 3. interactive_timeout覆盖wait_tim ...