组合:

夺命三问:
  1.什么是组合?
    组合指的是一个对象中,包含另一个或多个对象。

  2.为什么要用组合?
    减少代码的冗余。

  3.如何使用组合?

耦合度:
  耦: 莲藕 ---> 藕断丝连
  - 耦合度越高: 程序的可扩展性越低。
  - 耦合度越低: 程序的可扩展性越高。

总结:
  - 继承:
    继承是类与类的关系,子类继承父类的属性/方法,子类与父类是一种 “从属” 关系。

  - 组合:
    组合是对象与对象的关系,一个对象拥有另一个对象中的属性/方法,是一种什么有什么的关系。

# 组合实现
class People:
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex # 老师类
class Teacher(People):
def __init__(self, name, age, sex):
super().__init__(name, age, sex) # 学生类
class Student(People):
def __init__(self, name, age, sex):
super().__init__(name, age, sex) # 日期类
class Date:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day def tell_birth(self):
print(f'''
===== 出生年月日 =====
年: {self.year}
月: {self.month}
日: {self.day}
''') # tea1 = Teacher('tank', 17, 'male', 2002, 6, 6)
# print(tea1.name, tea1.age, tea1.sex)
# tea1.tell_birth()
# tea1 = Teacher('tank', 17, 'male')
# stu1 = Student('HCY', 109, 'female', 1910, 11, 11) stu1 = Student('HCY', 109, 'female')
date_obj = Date(1910, 11, 11)
# 学生对象中包含一个自定义日期对象
stu1.date_obj = date_obj
# print(stu1.name, stu1.age, stu1.sex)
# print(stu1.date_obj.year, stu1.date_obj.month, stu1.date_obj.day)
stu1.date_obj.tell_birth()

组合练习:

练习需求:
  选课系统:
    1.有学生、老师类,学生与老师有属性 “名字、年龄、性别、课程”,
    2.有方法 老师与学生可以添加课程, 打印学习/教授课程。

  # 组合实现

'''简洁版
练习需求:
选课系统:
1.有学生、老师类,学生与老师有属性 “名字、年龄、性别、课程列表”,
2.方法: 老师与学生可以添加课程, 打印学习/教授课程。 3.课程对象:
- 属性:
- 课程名字
- 课程价格
- 课程周期 - 方法:
- 打印当前课程信息 # 组合实现
''' class People:
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex # 添加课程
def add_course(self, course_obj): # self ---> stu1
# self.course_name = course_name
# self.course_price = course_price
# self.course_time = course_time
# self.course_list.append(course_obj) # [课程对象1, 课程对象2, ...]
self.course_list.append(course_obj) # [python_obj, go_obj] # 打印当前对象中课程列表的所有课程信息
# ---》 打印所有课程
def tell_all_course_info(self): # self ---> stu1 # 从当前对象中课程列表中取出所有的课程对象
# self.course_list == [python_obj, go_obj]
for course_obj in self.course_list: # 1.course_obj ---> python_obj
# 2.course_obj ---> go_obj # 通过课程对象.打印课程信息方法
course_obj.tell_course_info() # python_obj.tell_course_info() go_obj.tell_course_info() class Student(People):
# 假设从程序开始到灭亡 在实例化时都不修改该对象的属性
def __init__(self, name, age, sex):
super().__init__(name, age, sex) # 为当前对象添加课程列表属性 ---》 []
self.course_list = [] class Teacher(People):
def __init__(self, name, age, sex):
super().__init__(name, age, sex) # 为当前对象添加课程列表属性 ---》 []
self.course_list = [] # 定义一个课程类: 课程有: 课程名称, 课程价格, 课程周期
class Course:
def __init__(self, course_name, course_price, course_time):
self.course_name = course_name
self.course_price = course_price
self.course_time = course_time # 定义打印课程方法: 只打印当前课程信息
def tell_course_info(self):
print(f'''
====== 课程信息如下 ======
课程名称: {self.course_name}
课程价格: {self.course_price}
课程周期: {self.course_time}
''') # 学生对象stu1: 属性: name, age, sex, course_list 方法: add_course, tell_all_course_info
stu1 = Student('韩新宇', 18, 'female') # 课程对象: 属性: course_name, course_price, course_time 方法: tell_course_info
python_obj = Course('python', 20000, 6)
go_obj = Course('go', 28000, 5) # 学生调用添加课程功能
stu1.add_course(python_obj)
stu1.add_course(go_obj) # 学生调用打印 学生课程列表中所有课程的信息
stu1.tell_all_course_info()
class People:
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex # 打印出生日期方法
def tell_birth(self):
print(f'''
年: {self.date_obj.year}
月: {self.date_obj.month}
日: {self.date_obj.day}
''') # 添加课程
def add_course(self, course_obj):
# self.course_name = course_name
# self.course_price = course_price
# self.course_time = course_time
self.course_list.append(course_obj) # 打印当前对象中课程列表的所有课程信息
# ---》 打印所有课程
def tell_all_course_info(self):
# 从当前对象中课程列表中取出所有的课程对象
for course_obj in self.course_list:
# 通过课程对象.打印课程信息方法
course_obj.tell_course_info() class Student(People):
# 假设从程序开始到灭亡 在实例化时都不修改该对象的属性
def __init__(self, name, age, sex):
super().__init__(name, age, sex)
self.course_list = [] class Teacher(People):
def __init__(self, name, age, sex):
super().__init__(name, age, sex)
self.course_list = [] class Date:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day # 定义一个课程类: 课程有: 课程名称, 课程价格, 课程周期
class Course:
def __init__(self, course_name, course_price, course_time):
self.course_name = course_name
self.course_price = course_price
self.course_time = course_time # 定义打印课程方法 : 只打印一个课程信息
def tell_course_info(self):
print(f'''
====== 课程信息如下 ======
课程名称: {self.course_name}
课程价格: {self.course_price}
课程周期: {self.course_time}
''') # 创建学生对象
stu1 = Student('HCY', 2000, 'female & male')
date_obj = Date('公元19', '', '')
stu1.date_obj = date_obj
# stu1.tell_birth() # 创建课程对象
python_obj = Course('python', 77777, 6)
go_obj = Course('go', 88888, 4) # 当前学生添加了课程对象
# 添加python课程
stu1.add_course(python_obj)
# 添加go课程
stu1.add_course(go_obj) # 当前学生打印所有课程信息
stu1.tell_all_course_info()

封装介绍

夺命三问:
  1.什么是封装?
    封: 比如将一个袋子,封起来。
    装: 比如将一堆小猫、小狗和jason装在袋子里。
    # 对象 ---> 相当于一个袋子
    封装指的是可以将一堆属性和方法,封装到对象中。

    PS: 对象就好比一个 “袋子/容器”,可以存放一对属性和方法。
    PS: 存不是目的,目的是为了取,可以通过 “对象.” 的方式获取属性或方法。

  2.为什么要封装?
    可以通过 “对象.” 的方式 “存放/获取” 属性或方法。
    对象拥有 "." 的机制。
    方便数据的存取。

  3.如何封装?

class User:
  x = 10
  def func():
    pass
obj = User()
obj.y = 20
obj ---> x, func, y

访问限制机制

夺命三问:
  1.什么是访问限制机制?
    凡是在类内部定义的属性或方法,
    以__开头的属性或方法名,都会被限制,外部不能 “直接访问” 该属性原型。
    PS: 看着像将该属性或方法隐藏起来了。

    # python特有的:
    注意: 凡是在类内部定义__开头的属性或方法,都会变形为 _类名__属性/方法。

  2.为什么要有访问限制?
    比如: 将一些隐私的数据,隐藏起来,不让外部轻易获取。

    - 接口:
      可以将一对数据封装成一个接口, 可以让用户调用接口,
      并且通过相应的逻辑,最后再将数据返回给用户。

  3.如何实现?

# demo1
class User:
# __开头的属性
__name = 'tank' # __name变形为 ---》 _类名__name # __开头的方法
def __run(self):
print('tank is running...') print(User.__name)
obj = User()
print(obj._User__name)
# demo2
class User:
# __开头的属性
__name = 'tank' # __name变形为 ---》 _类名__name
__age = 17
__sex = 'male'
__ID = ''
__bal = 151651651651654654654
# def __init__(self, name, age, sex):
# self.__name = name
# self.__age = age
# self.__sex = sex
# 校验接口,获取用户信息
def parse_user(self, username, password):
if username == 'tank_jam' and password == '':
print(f'''
通过验证,获取用户信息。
用户名: {self.__name}
用户年龄: {self.__age}
用户性别: {self.__sex}
身份ID: {self.__ID}
用户资产: {self.__bal}
''')
else:
print('校验失败, 无法查询用户信息!') obj = User()
obj.parse_user('tank_jam', '')
# demo3:
class ATM:
# 取钱功能:
# 1.插入磁卡
def __insert_card(self):
print('开始插卡...')
pass
# 2.输入密码
def __input_pwd(self):
print('输入密码...')
pass
# 3.输入取款金额
def __input_bal(self):
print('输入取款金额...')
pass
# 4.吐钱
def __output_money(self):
print('开始吐钱...')
pass
# 5.打印流水账单
def __print_flow(self):
print('打印流水账单...')
pass # 取款顺序规范接口:
def withdraw(self):
# 1.插入磁卡
self.__insert_card()
# 2.输入密码
self.__input_pwd()
# 3.输入取款金额
self.__input_bal()
# 4.吐钱
self.__output_money()
# 5.打印流水账单
self.__print_flow() amt_obj = ATM()
amt_obj.withdraw()

考题分析

class A:
def __func(self):
print('from A.__func') def test(self):
self.__func() # 从B类中找,但是B类已变形_B__func,返回A类寻找 class B(A):
def __func(self):
print('from B.__func') b_obj = B()
b_obj.test() # from A.__func

内置装饰器property

夺命三问:
  1.什么是property?
    是一个python内置的装饰器,可以装饰在"类内部的方法"上。
    可以将该方法调用方式由 ----> 对象.方法() ---> 对象.方法

  2.为什么用property?
    PS: 在某些场景下,调用的方法只是用来获取计算后的某个值。
    PS: 必须通过 对象.方法() 方式调用,让该方法看起来像动词。

    让名词的方法,调用时更为合理。
    目的是为了,迷惑调用者,调用的方法误以为是 属性。

3.如何用?

# 需求: 计算人体 bmi 指数
# 体重 / 身高的平方
# value = weight / (height * height)
class User:
def __init__(self,name,weight,height):
self.__name=name
self.weight=weight
self.height=height
@property # 获取bmi指数方法
def bmi(self):
return self.weight/(self.height**2)
@property
def name(self):
return self.__name # 了解: 设置被property装饰后的方法
# 注意: 需要修改的方法名字要与被property装饰器后的方法一样
@name.setter
def name(self,value):
self.__name = value
@name.deleter
def name(self): # 删除属性
del self.__name user_obj = User('HCY',100,1.9)
print(user_obj.bmi)
print(user_obj.name) # 修改属性
user_obj.name='ZSB'
print(user_obj.name) # 删除属性
del user_obj.name
print(user_obj.name) # # 报错

python基础语法16 面向对象3 组合,封装,访问限制机制,内置装饰器property的更多相关文章

  1. 【python基础语法】OS模块处理文件绝对路径,内置的异常类型、捕获、处理(第9天课堂笔记)

    import os """ 通过文件的路径去打开文件 相对路径:相对当前的工作路径去定位文件位置 .:代表当前路径 ..:代表上一级路径(父级路径) 绝对路径:相对于电脑 ...

  2. Python内置装饰器@property

    在<Python装饰器(Decorators )>一文中介绍了python装饰器的概念,日常写代码时有一个装饰器很常见,他就是内置的@property. 我们一步步的来接近这个概念. 一个 ...

  3. python内置装饰器

    前言 接着上一篇笔记,我们来看看内置装饰器property.staticmethod.classmethod 一.property装饰器 1. 普通方式修改属性值 code class Celsius ...

  4. python进阶04 装饰器、描述器、常用内置装饰器

    python进阶04 装饰器.描述器.常用内置装饰器 一.装饰器 作用:能够给现有的函数增加功能 如何给一个现有的函数增加执行计数的功能 首先用类来添加新功能 def fun(): #首先我们定义一个 ...

  5. python基础语法_3面向对象

    http://www.runoob.com/python3/python3-class.html https://www.imooc.com/learn/317 慕课网:987809563@qq.co ...

  6. python基础语法17 面向对象4 多态,抽象类,鸭子类型,绑定方法classmethod与staticmethod,isinstance与issubclass,反射

    多态 1.什么是多态? 多态指的是同一种类型的事物,不同的形态. 2.多态的目的: “多态” 也称之为 “多态性”,目的是为了 在不知道对象具体类型的情况下,统一对象调用方法的规范(比如:名字). 多 ...

  7. python基础语法20 面向对象5 exec内置函数的补充,元类,属性查找顺序

    exec内置函数的补充 exec: 是一个python内置函数,可以将字符串的代码添加到名称空间中; - 全局名称空间 - 局部名称空间 exec(字符串形式的代码, 全局名称空间, 局部名称空间) ...

  8. python基础语法15 面向对象2 继承,多态,继承json模块中JSONEncoder,并派生出新的功能

    继承 1.什么是继承? 继承是一种新建类的方式,新建的类称之为子类或派生类,继承的父类称之为基类或超类. - 在Python中,一个子类可以继承多个父类.(面试可能会问) - 在其它语言中,一个子类只 ...

  9. 面向对象——组合、封装、访问限制机制、property内置装饰器

    面向对象--组合.封装.访问限制机制.property 组合 什么是组合? 组合指的是一个对象中,包含另一个或多个对象 为什么要组合? 减少代码的冗余 怎么用组合? # 综合实现 # 父类 class ...

随机推荐

  1. [LeetCode] 505. The Maze II 迷宫之二

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  2. [LeetCode] 29. Divide Two Integers 两数相除

    Given two integers dividend and divisor, divide two integers without using multiplication, division ...

  3. MySQL中的相关表操作

    简单表操作 1.表操作之修改表 .修改表名 alter table 表名 rename 新表名 .增加字段 alter table 表名 add 新字段名 数据类型[相关约束性条件...], add ...

  4. Nacos集成Spring Cloud Gateway 基础使用

    项目结构 项目 端口 描述 nacos-provider 8000 服务 nacos-getway 8001 网关 nacos-provider项目依赖 <dependencies> &l ...

  5. google 镜像

    google 镜像 http://scholar.hedasudi.com/ http://ac.scmor.com/

  6. Vue2 实践揭秘 错误列表

    京东上的购买地址 作者是土生土长的聪明中国人 https://item.jd.com/12176536.html 64页 const bookID = this.$router.params.id 搞 ...

  7. 《Interest Rate Risk Modeling》阅读笔记——第一章:利率风险建模概览

    目录 第一章:利率风险建模概览 思维导图 一些想法 第一章:利率风险建模概览 思维导图 一些想法 久期向量模型类似于研究组合收益的高阶矩. 久期向量模型用的是一般多项式表达高阶久期,试试正交多项式? ...

  8. [转帖]linux lsof 用法简介

    linux lsof 用法简介 https://www.cnblogs.com/saneri/p/5333333.html 1.简介: lsof(list open files)是一个列出当前系统打开 ...

  9. Appium+python自动化(四)- 如何查看程序所占端口号和IP(超详解)(番外篇)

    简介 这篇博文和分类看似没有多大关系,但是也是从上一篇衍生出来的产物,因为涉及到FQ工具Lantern,就算是给关注和支持的小伙伴们拓展一下眼界和知识面.而且好多人都阅读了上一篇没发现那个参考博客点不 ...

  10. Nginx 极简入门教程!

    上篇文章和大家聊了 Spring Session 实现 Session 共享的问题,有的小伙伴看了后表示对 Nginx 还是很懵,因此有了这篇文章,算是一个 Nginx 扫盲入门吧! 基本介绍 Ngi ...