文章部分转自:https://github.com/jackh001/python100Day/blob/master


自己的话:读书不觉已春深,一寸光阴一寸金
一台大G正在向我家车库驶来
眼泪你别问 . joker这个男人你别恨


面向对象编程基础与进阶

什么是面向对象的编程:
把一组数据结构和处理它们的方法组成对象,把相同行为的对象归纳为类,通过类的封装隐藏内部细节,通过继承实现类的特化和泛化,通过多态实现基于对象类型的动态分派。

一、类和对象

类是对象的蓝图和模板,而对象是类的实例。

1.定义类

**在Python中可以使用class关键字定义类,**然后在类中通过之前学习过的函数来定义方法,这样就可以将对象的动态特征描述出来,代码如下所示:

# 在Python2中这个object一定要写,但是在Python3中可写可不写(**默认就继承了object**).
#
class Student(object):# __init__是一个特殊方法用于在创建对象时进行初始化操作# 通过这个方法我们可以为学生对象绑定name和age两个属性def __init__(self, name, age):self.name = nameself.age = agedef study(self, course_name):print('%s正在学习%s.' % (self.name, course_name))def watch_av(self):if self.age < 18:print('%s只能观看《熊出没》.' % self.name)else:print('%s正在观看岛国爱情动作片.' % self.name
# 实例
student = Student()
# PEP 8要求标识符的名字用全小写多个单词用下划线连接# 但是很多程序员和公司更倾向于使用驼峰命名法(驼峰标识)#例如,下面是分别用骆驼式命名法和下划线法命名的同一个函数:#printEmployeePaychecks();#print_employee_paychecks();#第一个函数名使用了骆驼式命名法——函数名中的每一个逻辑断点都有一个大写字母来标记;第二个函数名使用了下划线法----函数名中的每一个逻辑断点都有一个下划线来标记。

写在类中的函数,我们通常称之为(对象的)方法,这些方法就是对象可以接收的消息

class Student(object):"""第二步初始化,初始化自己.当你的类有一些公用变量的时候,你就可以初始化初始化中经常放入公有的变量."""def __init__(self,name):"""在类中,一切的变量和函数都要印记(self)"""self.name = namedef def1(self,num):self.num = numprint(self.num)print(self.name)def def2(self):print(self.num)print(self.name)if __name__ == "__main__":# 实例,类名带括号“Student()”,直接运行初始化函数student = Student('Jasmine')student.def1(100)student.def2()结果:
100
Jasmine
100
Jasmine

(*)课堂截图

2.创建和使用对象

当我们定义好一个类之后,可以通过下面的方式来创建对象并给对象发消息:

def main():# 创建学生对象并指定姓名和年龄stu1 = Student('jasmine', 18)# 给对象发study消息stu1.study('大数据一班')# 给对象发watch_av消息stu1.watch_av()stu2 = Student('joker', 25)stu2.study('也不行')stu2.watch_av()if __name__ == '__main__':main()

3.访问可见性问题

在很多面向对象编程语言中,我们通常会将对象的属性设置为私有的(private)或受保护的(protected),简单的说就是不允许外界访问,而对象的方法通常都是公开的(public),因为公开的方法就是对象能够接受的消息。**在Python中,属性和方法的访问权限只有两种,也就是公开的和私有的,如果希望属性是私有的,在给属性命名时可以用两个下划线作为开头。**下面的代码可以验证这一点:

# 私有变量,变量名前面加"__"
# 如果非要使用私有变量,那么可以使用dir(class())去查看它真正的名字.
# 私有变量/函数,在类内部可以直接调用.
# 如果你想体现一个变量/函数特别重要你可以使用"_"
class Test:def __init__(self, foo):self.__foo = foodef __bar(self):print(self.__foo)print('__bar')def main():test = Test('hello')# AttributeError: 'Test' object has no attribute '__bar'test.__bar()# AttributeError: 'Test' object has no attribute '__foo'print(test.__foo)if __name__ == "__main__":main()

但是,Python并没有从语法上严格保证私有属性或方法的私密性,它只是给私有的属性和方法换了一个名字来“妨碍”对它们的访问,事实上如果你知道更换名字的规则仍然可以访问到它们,下面的代码就可以验证这一点:

class Test:def __init__(self, foo):self.__foo = foodef __bar(self):print(self.__foo)print('__bar')def main():test = Test('hello')test._Test__bar()print(test._Test__foo)if __name__ == "__main__":main()

在实际开发中,我们并不建议将属性设置为私有的,因为这会导致子类无法访问

4.@property装饰器

之前我们讨论过Python中属性和方法访问权限的问题,虽然我们不建议将属性设置为私有的,但是如果直接将属性暴露给外界也是有问题的,比如我们没有办法检查赋给属性的值是否有效。我们之前的建议是将属性命名以单下划线开头,通过这种方式来暗示属性是受保护的,不建议外界直接访问,那么如果想访问属性可以通过属性的getter(访问器)和setter(修改器)方法进行对应的操作。如果要做到这点,就可以考虑使用@property包装器来包装getter和setter方法,使得对属性的访问既安全又方便,代码如下所示:

class Person(object):def __init__(self, name, age):self._name = nameself._age = age# 访问器 - getter方法@propertydef name(self):return self._name# 访问器 - getter方法@propertydef age(self):return self._age# 修改器 - setter方法@age.setterdef age(self, age):self._age = agedef play(self):if self._age <= 16:print('%s正在欢乐海沙滩晒太阳.' % self._name)else:print('%s正在出海.' % self._name)def main():person = Person('Jasmine', 18)person.play()person.age = 22person.play()# person.name = '啥玩意'  # AttributeError: can't set attributeif __name__ == '__main__':main()

(*)课堂截图:

访问器(装饰器):把函数变成了一个属性

5.__slots__魔法

我们讲到这里,不知道大家是否已经意识到,Python是一门动态语言。通常,动态语言允许我们在程序运行时给对象绑定新的属性或方法,当然也可以对已经绑定的属性和方法进行解绑定。但是如果我们需要限定自定义类型的对象只能绑定某些属性,可以通过在类中定义__slots__变量来进行限定。需要注意的是__slots__的限定只对当前类的对象生效,对子类并不起任何作用。

class Person(object):# 限定Person对象只能绑定_name, _age和_gender属性__slots__ = ('_name', '_age', '_gender')def __init__(self, name, age):self._name = nameself._age = age@propertydef name(self):return self._name@propertydef age(self):return self._age@age.setterdef age(self, age):self._age = agedef play(self):if self._age <= 16:print('%s正在玩水.' % self._name)else:print('%s正在玩蛇.' % self._name)def main():person = Person('joker', 39)person.play()person._gender = '男'# AttributeError: 'Person' object has no attribute '_is_gay'# person._is_gay = True

课堂截图(动态绑定):

结果为:100000

课堂截图:

下面要print,上面就要有return返回值,否则会打印None。

上图中的这两个 joker.a,第一个走的是修改器,第二个走的是装饰器。

6.静态方法和类方法

之前,我们在类中定义的方法都是对象方法,也就是说这些方法都是发送给对象的消息。实际上,我们写在类中的方法并不需要都是对象方法。属于类而并不属于对象的,我们可以使用静态方法来解决这类问题:

静态方法的使用方法

例如:我们定义一个“三角形”类,通过传入三条边长来构造三角形,并提供计算周长和面积的方法,但是传入的三条边长未必能构造出三角形对象,因此我们可以先写一个方法来验证三条边长是否可以构成三角形,这个方法很显然就不是对象方法,因为在调用这个方法时三角形对象尚未创建出来(因为都不知道三条边能不能构成三角形),所以这个方法是属于三角形类而并不属于三角形对象的。我们可以使用静态方法来解决这类问题,代码如下所示:

from math import sqrtclass Triangle(object):def __init__(self, a, b, c):self._a = aself._b = bself._c = c@staticmethoddef is_valid(a, b, c):return a + b > c and b + c > a and a + c > bdef perimeter(self):return self._a + self._b + self._cdef area(self):half = self.perimeter() / 2return sqrt(half * (half - self._a) *(half - self._b) * (half - self._c))def main():a, b, c = 3, 4, 5# 静态方法和类方法都是通过给类发消息来调用的if Triangle.is_valid(a, b, c):t = Triangle(a, b, c)print(t.perimeter())# 也可以通过给类发消息来调用对象方法但是要传入接收消息的对象作为参数# print(Triangle.perimeter(t))print(t.area())# print(Triangle.area(t))else:print('无法构成三角形.')if __name__ == '__main__':main()

7.类之间的关系

简单的说,类和类之间的关系有三种:is-a、has-a和use-a关系。

  • is-a关系也叫继承或泛化,比如学生和人的关系、手机和电子产品的关系都属于继承关系。
  • has-a关系通常称之为关联,比如部门和员工的关系,汽车和引擎的关系都属于关联关系;关联关系如果是整体和部分的关联,那么我们称之为聚合关系;如果整体进一步负责了部分的生命周期(整体和部分是不可分割的,同时同在也同时消亡),那么这种就是最强的关联关系,我们称之为合成关系。
  • use-a关系通常称之为依赖,比如司机有一个驾驶的行为(方法),其中(的参数)使用到了汽车,那么司机和汽车的关系就是依赖关系。

二、继承和多态

刚才我们提到了,可以在已有类的基础上创建新类,这其中的一种做法就是让一个类从另一个类那里将属性和方法直接继承下来,从而减少重复代码的编写。提供继承信息的我们称之为父类,也叫超类或基类;得到继承信息的我们称之为子类,也叫派生类或衍生类。子类除了继承父类提供的属性和方法,还可以定义自己特有的属性和方法,所以子类比父类拥有的更多的能力,下面我们先看一个继承的例子:

class Person(object):"""人"""def __init__(self, name, age):self._name = nameself._age = age@propertydef name(self):return self._name@propertydef age(self):return self._age@age.setterdef age(self, age):self._age = agedef play(self):print('%s正在愉快的玩耍.' % self._name)def watch_av(self):if self._age >= 18:print('%s正在观看爱情动作片.' % self._name)else:print('%s只能观看《熊出没》.' % self._name)class Student(Person):"""学生"""def __init__(self, name, age, grade):super().__init__(name, age)self._grade = grade@propertydef grade(self):return self._grade@grade.setterdef grade(self, grade):self._grade = gradedef study(self, course):print('%s的%s正在学习%s.' % (self._grade, self._name, course))class Teacher(Person):"""老师"""def __init__(self, name, age, title):super().__init__(name, age)self._title = title@propertydef title(self):return self._title@title.setterdef title(self, title):self._title = titledef teach(self, course):print('%s%s正在讲%s.' % (self._name, self._title, course))def main():stu = Student('jasmine', 18, '高三')stu.study('计算机')stu.watch_av()t = Teacher('joker', 39, '老程序猿')t.teach('水学')t.watch_av()if __name__ == '__main__':main()

课堂截图(继承):

注意:1.括号里写目标。
2.在子类初始化父类。

不想学python也不想写博客的第四天相关推荐

  1. 还在犹豫写不写博客吗?

    扬帆起航吧少年 为什么我要开始写博客 你为什么还在犹豫 最后 坚持,坚持,坚持!!! 为什么我要开始写博客 The most important reason,我想记录生活 ,记录自己的成长(想一想再 ...

  2. Python Web企业门户网站—系列博客教程介绍

    本系列教程将使用Python Web的Django框架实现企业门户网站的制作.本教程一共分为8篇博文,将从最基础的Python语法讲起,然后使用Django3逐步搭建一个完整的企业门户网站项目实例.如 ...

  3. 程序员写博客的意义何在?为什么推荐程序员写个人博客?

    我为什么推荐大家写博客 您为什么不写博客? 开始我的主题前,我想先问下此刻在看博客的你,为什么不写博客? 当然你既然点开了这篇文章.那么我就认为你不是极端主义者,你不会想的是我就不写,写博客有jb用之 ...

  4. 学python应该掌握的英语单词怎么写_想学Python但是有好多英语单词不认识,Python的常见英语单词都在这儿...

    想学python但是有好多英文单词不认识怎么办? 以下是python代码编写和提示信息中的常用和常见的英文单词. 不需要背,看得多了用到的多了就熟悉了. 另外,我为大家准备了2020最新的学习资料,路 ...

  5. 想学python编程-想学Python编程?你真的适合吗?

    原标题:想学Python编程?你真的适合吗? 有的人说我想学什么.我想干什么,很多时候都是头脑发热,单凭一腔热血,可是这样的路即便走上去你又能坚持多久呢?所以,每每有人问我学Python编程怎么样,我 ...

  6. python对英语和数学的帮助-英语和数学都不好,但是我想学Python编程可以吗?

    我们有很多人想要做某件事之前都会产生畏难情绪,比如有很多人问:英语和数学都不好,但是我想学Python编程可以吗?你们大家说可以吗?可以,为什么呢?不可以,为什么呢? 收到很多咨询的留言,学生总是会问 ...

  7. 学python需要什么-想要学人工智能需要学些什么python的知识

    人工智能包含常用机器学习和深度学习两个很重要的模块,而python拥有matplotlib.Numpy.sklearn.keras等大量的库,像pandas.sklearn.matplotlib这些库 ...

  8. python基础教程第三版豆瓣-想学python,请问有没好的书籍推荐?

    假如像楼主所说,PHP 市场饱和度太高,那学一门新语言考虑转型其实没啥大问题.不过看楼主的描述,似乎目前对 PHP 的掌握并不深入.不清楚为啥想学 Python,尽管 Python 有挺多亮点,而且做 ...

  9. 数学不好、英语不好、非本专业,想学python数据分析,能安排吗?

    全世界有3.14 % 的人已经关注了 数据与算法之美 "非本专业想转型做数据分析,有救吗?" "数学不好,英语不好,想学Python数据分析,有救吗?" &qu ...

最新文章

  1. opencv 采用 matplot 显示图片
  2. http 请求(tomcat) 返回 错误页面信息
  3. 进击吧! Blazor !第五期 安全
  4. 静态方法和实例方法(mark)
  5. java例程练习(东软笔试题——n阶平面魔方)
  6. c 连接mysql通用_用C语言操作MySQL数据库的通用方法
  7. 数据库加密乱码_加密数据库中的密码
  8. w7 internet信息服务器,Win7安装IIS Internet信息服务步骤
  9. 《个人信息去标识化指南》笔记
  10. 新手淘客你必须知道的秘密
  11. 用c语言实现基本数据结构(图)
  12. cruzer php sandisk 闪迪u盘量产工具_SanDisk Cruzer CZ36闪迪U盘 怎么量产
  13. 微信支付获取用户真实ip
  14. 支付宝崩了登上微博热搜
  15. win10系统通过WSL/WSL2安装各种linux版本,开启图形桌面
  16. python勾股定理、0-30_求助python大神,显示Process finished with exit code 0.
  17. EOJ - 我决不会TLE (一个智障的题目)
  18. leetcode: 70. Climbing Stairs
  19. 信息系统项目管理:项目经理担任什么样的角色?
  20. 软件开发过程的五个阶段

热门文章

  1. 针对 华为 荣耀5X root(有bootloader锁)---【亲测刷机】
  2. Linux shell脚本编程实例
  3. 蓝桥杯比赛个人注意事项
  4. jQuery页面刷新的一些方法
  5. 【SEO联盟】老域名历史批量查询软件
  6. 线性代数学习笔记——第四十五讲——线性相关性的判定
  7. 进行渗透测试的详细检测方法
  8. 2022胺基化工艺考试试题及答案
  9. mac配置flutter一条龙
  10. LeetCode1218