python之路--day21--组合与封装

讲在组合之前: 

  解决类和类之间代码冗余问题有两种解决方案:1,继承  2,组合

  1,继承:描述的是类和类之间,什么是什么的关系,一种从属关系

  2,组合:描述的是类和类之间的关系。是一种什么有什么的关系

组合:一个类产生的对象,该对象拥有一个属性,这个属性的值来自于另外一个类的对象

  

class OldboyPeople:
    school = ‘oldboy‘

    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
class OldboyTeacher(OldboyPeople):
       def __init__(self,name,age,sex,level,salary):
             super().__init__(name,age,sex)
             self.level=level
             self.salary = salary
       def change_score(self):
            print(‘......................‘)
class OldboyTeacher(OldboyPeople):
       def __init__(self,name,age,sex,course):
             super().__init__(name,age,sex)
             self.course = course
       def change_score(self):
            print(‘......................‘)

tea1 = OldboyTeacher(‘egon‘,18,‘male‘,9,3.1)
data_obj = Data(2000,1,1)

tea1.birth = data_obj
##
##
此处:为tea1对象新增了一个属性birth,这个属性的值是Data实例化的对象data_obj....这就是类的组合
##
##

类的组合

class OldboyPeople:
    school = ‘oldboy‘

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

class OldboyTeacher(OldboyPeople):
    def __init__(self,name,age,sex,level,salary):
        super().__init__(name,age,sex)
        self.level=level
        self.salary=salary

        self.courses=[]

    def change_score(self):
        print(‘teacher %s is changing score‘ %self.name)

    def tell_course_info(self):
        print((‘老师%s 教授的课程信息如下‘ %self.name).center(50,‘=‘))
        for course_obj in self.courses:
            course_obj.info()

class Oldboystudent(OldboyPeople):
    def __init__(self,name,age,sex):
        super().__init__(name,age,sex,)
        self.courses=[]

    def choose(self):
        print(‘student %s choose course‘ %self.name)

    def tell_course_info(self):
        print((‘学生%s 学习的课程信息如下‘ % self.name).center(50, ‘=‘))
        for course_obj in self.courses:
            course_obj.info()

class Course:
    def __init__(self,cname,period,price):
        self.cname=cname
        self.period=period
        self.price=price

    def info(self):
        print(‘课程信息<名字:%s 周期:%s  价钱:%s>‘ %(self.cname,self.period,self.price))

tea1=OldboyTeacher(‘egon‘,18,‘male‘,9,3.1)
stu1=Oldboystudent(‘张三‘,16,‘male‘)

python=Course(‘Python全栈开发‘,‘5mons‘,3000)
linux=Course(‘Linux高级架构师‘,‘5mons‘,2000)
go=Course(‘Go开发工程师‘,‘3mons‘,1000)

# # 给老师添加课程
# tea1.courses.append(python)
# tea1.courses.append(linux)

# print(tea1.courses)
# tea1.courses[0].info()
# for course_obj in tea1.courses:
#     course_obj.info()

# tea1.tell_course_info()

# 给学生添加课程
stu1.courses.append(python)
stu1.courses.append(go)
stu1.courses.append(linux)
stu1.tell_course_info()

组合练习

封装:

  什么是封装:

    装就是把一堆属性存起来,封就是把这些属性给隐藏起来

    强调:封装单从字面意思看就等同于隐藏,但其实封装绝对不是单纯意义的隐藏

  为什么要用封装:

    最终目的:明确区分内外,对内部开发,对外部隐藏

    封装数据属性的目的:把数据属性封装起来,然后需要开辟接口给类外部的使用者使用。然后在接口上添加控制逻辑,

        从而严格控制访问者对属性的操作

        

class People:
    def __init__(self,name,age):
        self.__name=name
        self.__age=age

    def tell_info(self):

            print(self.__name,self.__age)

    def set_info(self,name,age):
        if type(name) is not str:
            raise TypeError(‘用户名必须为str类型‘)
        if type(age) is not int:
            raise TypeError(‘年龄必须为int类型‘)
        self.__name=name
        self.__age=age

数据属性的封装

    封装函数属性的目的:隔离复杂度

 

class ATM:
    def __card(self):
        print(‘插卡‘)
    def __auth(self):
        print(‘用户认证‘)
    def __input(self):
        print(‘输入取款金额‘)
    def __print_bill(self):
        print(‘打印账单‘)
    def __take_money(self):
        print(‘取款‘)

    def withdraw(self):
        self.__card()
        self.__auth()
        self.__input()
        self.__print_bill()
        self.__take_money()

obj=ATM()
obj.withdraw()

函数属性的封装

  如何用封装

    在属性前面就是 __开头(一定注意不要加__结尾)

    特征:1,__开头隐藏属性,只是语法上的一种变形,对外不对内

        什么是对外不对内:为一个属性加__开头,会在类定义阶段将属性名统一变形为:_ 自己的类名__ 属性名

        

class Foo:
    __x=1111             #_Foo__x=1111
    def __init__(self,y):
        self.__y=y         #self._Foo__y=y

    def __f1(self):         #_Foo__f1
        print(‘Foo.f1‘)

    def get_y(self):
        print(self.__y)     # print(self._Foo__y)            

#类内部在定义阶段全部做了语法上的修改,所以内部可以访问__开头的属性

#但是类外部无法直接通过属性名访问类内部属性    

__开头封装类属性

       2,这种语法上的变形,只在类定义阶段生效一次,定义阶段之后再定义的__开头的属性,没有隐藏的效果

# Foo.__aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=1
# print(Foo.__dict__)

# obj.__bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb=2
# print(obj.__dict__)

类定义之后再定义的__开头

      3,如果父类不想子类覆盖掉自己的属性,可以在定义阶段在使用__开头,隐藏属性、

class Foo:
    def __f1(self): #_Foo__f1
        print(‘Foo.f1‘)

    def f2(self):
        print(‘Foo.f2‘)
        self.__f1()    #obj._Foo__f1()

class Bar(Foo):
    def __f1(self): #_Bar__f1
        print("Bar.f1")

obj=Bar()

obj.f2()

不让子类覆盖父类的同名属性

原文地址:https://www.cnblogs.com/guodengjian/p/8823930.html

时间: 2024-11-04 06:45:59

python之路--day21--组合与封装的相关文章

Python之路,Day21 - 常用算法学习

Python之路,Day21 - 常用算法学习 本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出.如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题.不同的算法可能用不同的时间.空间或效率来完成同样的任务.一个算法的优劣可以用空间复杂度与时间复杂度来衡量. 一个算

python之路,Day24 常用设计模式学习

python之路,Day24 常用设计模式学习 本节内容 设计模式介绍 设计模式分类 设计模式6大原则 1.设计模式介绍 设计模式(Design Patterns) --可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一

Python之路【第十三篇续】jQuery案例-Form表单&amp;插件及扩展

jQuery案例-Form表单 学完这个form表单的案例,如果有人说这个表单(功能)还不够NB(此文不包含样式,样式是CSS比较简单可以根据需求自己添加),那么找武Sir他帮你搞定. 一步一步来 注意事项(目录结构): 在写前端html代码的时候要注意(任何代码都一样),一定要规划好目录结构方便其他的人来看你的代码! 如果还有其他的html页面可以在加一个html存储的文件夹. 1.首先看下HTML主体 <!DOCTYPE html> <html lang="en"

Python之路【第十三篇】jQuery案例-Form表单&amp;插件及扩展

学完这个form表单的案例,如果有人说这个表单(功能)还不够NB(此文不包含样式,样式是CSS比较简单可以根据需求自己添加),那么找武Sir他帮你搞定. 一步一步来 注意事项(目录结构): 在写前端html代码的时候要注意(任何代码都一样),一定要规划好目录结构方便其他的人来看你的代码! 如果还有其他的html页面可以在加一个html存储的文件夹. 1.首先看下HTML主体 <!DOCTYPE html> <html lang="en"> <head>

Python之路【第九篇】:Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy

Python之路[第九篇]:Python操作 RabbitMQ.Redis.Memcache.SQLAlchemy Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度.Memcached基于一个存储键/值对的hashmap.其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信. Memc

七日Python之路--第十二天(Django Web 开发指南)

<Django Web 开发指南>.貌似使用Django1.0版本,基本内容差不多,细读无妨.地址:http://www.jb51.net/books/76079.html (一)第一部分 入门 (1)内置数字工厂函数 int(12.34)会创建一个新的值为12的整数对象,而float(12)则会返回12.0. (2)其他序列操作符 连接(+),复制(*),以及检查是否是成员(in, not in) '**'.join('**')   或  '***%s***%d' % (str, int)

Python之路【第三篇】:Python基础(二)

Python之路[第三篇]:Python基础(二) 内置函数 一 详细见python文档,猛击这里 文件操作 操作文件时,一般需要经历如下步骤: 打开文件 操作文件 一.打开文件 1 文件句柄 = file('文件路径', '模式') 注:python中打开文件有两种方式,即:open(...) 和  file(...) ,本质上前者在内部会调用后者来进行文件操作,推荐使用 open. 打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作.

Python之路【第十九篇】:爬虫

Python之路[第十九篇]:爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁.自动索引.模拟程序或者蠕虫. Requests Python标准库中提供了:urllib.urllib2.httplib等模块以供Http请求,但是,它的 API 太渣了.它是为另一个时代.另一个互联网所创建的.它需要巨量的工作,甚至包括各种方法覆盖,来完成最简单的任务. import

Python之路【第八篇】:堡垒机实例以及数据库操作

Python之路[第八篇]:堡垒机实例以及数据库操作 堡垒机前戏 开发堡垒机之前,先来学习Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接: + import paramiko transport = paramiko.Transport(('hostname', 22)) transport.connect(username='wupeiqi', password='123') ssh