汉皇重色思倾国,御宇多年求不得。 杨家有女初长成,养在深闺人未识。 天生丽质难自弃,一朝选在君王侧。 回眸一笑百媚生,六宫粉黛无颜色。 春寒赐浴华清池,温泉水滑洗凝脂。 侍儿扶起娇无力,始是新承恩泽时。 云鬓花颜金步摇,芙蓉帐暖度春宵。 春宵苦短日高起,从此君王不早朝。 承欢侍宴无闲暇,春从春游夜专夜。 后宫佳丽三千人,三千宠爱在一身。 金屋妆成娇侍夜,玉楼宴罢醉和春。 姊妹弟兄皆列土,可怜光彩生门户。 遂令天下父母心,不重生男重生女。 骊宫高处入青云,仙乐风飘处处闻。 缓歌慢舞凝丝竹,尽日君王看不足。 渔阳鼙鼓动地来,惊破《霓裳羽衣曲》。

1 面向对象和面向面向过程

1.1 面向对象

  • 面向对象是一种编程思想
  • 核心关注的是参与解决问题的对象以及他们的行为,把构成问题的各个事物分解成各个对象,将参与的对象抽取成类型,通过类型创建对应的对象
  • 最终通过对象之间的互相关联完成问题的解决
  • 实现方式:类和对象
  • 特点:复用性、扩展性特别好
  • 适用于拓展性要求较高的场景

1.2 面向过程

  • 面向过程是一种编程思想
  • 核心关注的是解决问题的步骤,将每个步骤封装成独立的函数,通过函数的依次调用执行,完成问题的处理,得到处理结果
  • 实现方式:函数式编程
  • 特点:稳定性好
  • 适用于稳定性要求较高的场景

2 类和对象

  • 类:类型的简称,是一系列对象的抽象概念,类型中包含了对象的特征属性的描述以及对象 的行为方法的声明
  • 对象:实际存在的物体,包含具体的属性特征和行为方法
  • 类和对象的关系:类是对象的模板,对象是类的实例,如人是一种类型,唐玄宗和杨贵妃是对象
  • 属性:事物具备的特征,如人的性别,年龄等,有类属性和对象属性
  • 方法:事物具备的行为,如人的吃饭睡觉行为,有类方法和对象方法

2.1 类的声明

语法:

class  类型名称:  # 声明类型即声明一种数据类型"""类型的文档注释"""def __init__(self):  # 对象的特征属性"""声明属性的方法"""passdef 类型中的方法(self):  # 对象的方法行为pass
  • 类型名称命名遵循标识符的规则(字母、数字、下划线组成,数字不能开头),见名知意,使用帕斯卡命名法(大驼峰命名法)
  • 属性名称、方法名称遵循标识符规则,变量命名规则(见名知意),使用下划线命名法
  • self关键字:在类型的声明中,可以通过 self描述当前的某个对象,类似生活中的“我”,每个对象都有一个自己的 self 关键字,self是约定俗成的用法,也可以用其他字符代替
# 声明人类型:
class Person:"""人的类型"""# 初始属性,姓名,性别,身份def __init__(self, name, gender, position):  # 初始属性self.name = nameself.gender = genderself.position = position# 娱乐的行为def entertainment(self, item):if item == "drum":print("渔阳鼙鼓动地来")elif item == "dance":print("惊破《霓裳羽衣曲》")else:print("骊宫高处入青云,仙乐风飘处处闻")

2.2 对象的创建和操作

语法:
  引用变量 = 类型名称( 属性参数列表)
创建了一个指定类型的对象,将对象在内存中的地址赋值给一个引用变量。

# 创建对象(续2.1中代码)
# 引用变量 = 类型名称(属性参数)
emperor = Person("李隆基", "男", "皇帝", "唐玄宗")
emperor_wife = Person("杨玉环", "女", "贵妃", "杨贵妃")

3 实例属性和实例方法

3.1 实例属性

  • 声明位置:声明在类型中的__init__()方法中,是每个对象独有的特征数据
  • 数据获取:对象的引用变量.属性名称
  • 数据修改(或新增):对象的引用变量.属性名称 = 新的数据(尽量避免用该方法新增数据)
# 操作对象的属性(续2.2代码):
# 获取数据: 引用变量.属性名称
print(emperor.name)  # 李隆基
print(emperor_wife.nickname)  # 杨贵妃
# 修改(或新增)数据:对象的引用变量.属性名称 = 新的数据
# 尽量避免用该方法新增数据
emperor.name = "唐明皇"
print(emperor.name)  # 唐明皇

3.2 实例方法

  • 声明在类型的内部的函数,函数的第一个参数是:self,是每个对象独有的行为
  • 类型中编写的self是一种固定语法,该类型创建的每个对象,都会有各自的self存在,对象通过self调用当前对象的属性/方法
  • 当函数一旦声明在类型中,就被称为类型的方法
  • 使用:对象的引用变量.方法名称(参数)
# 操作对象的方法(续3.1代码):
# 引用变量.方法名称([参数])
emperor_wife.grow_up()  # 杨家有女初长成,养在深闺人未识。
emperor.entertainment("drum")  # 渔阳鼙鼓动地来
emperor.entertainment("dance")  # 惊破《霓裳羽衣曲》

4 类属性

  • 声明在类型的内部,方法的外部,遵循变量的命名规范
  • 类属性属于类型的特征,可以被类型名称直接访问,可以被当前类型的所有对象访问
  • 类属性只能被类型名称修改
  • 类属性不能被对象修改(赋值)

访问:

  • 通过类型名称访问:类名.类属性变量
  • 通过对象直接访问:对象变量.类属性变量

修改(新增):

  • 通过类型名称修改(没有该变量则会新增属性):类名.类属性变量 = 数据

对象实例属性操作类属性(避免此操作):

  • 对象变量.类属性变量 = 数据
  • 对象变量.新属性变量 = 数据
  • 以上两种方式只改变该对象中的数据,类属性没有被修改
  • 不可变类型数据:
    都是给对象添加了属性,而不是修改类属性
  • 可变数据类型:
    如果对象是修改可变类型中的数据,是真正的修改(类属性也被修改)
    如果是重新给可变类型变量赋值,则是给对象添加属性
class Person:"""人的类型"""# 类属性nationality = "唐"# 可变数据类属性entertainment = ["渔阳鼙鼓动地来"]# 创建对象
emperor = Person()
emperor_wife = Person()# 可以通过类型名称访问:类名.类属性变量
print(Person.nationality)  # 唐# 可以通过对象直接访问:对象变量.类属性变量
print(emperor.nationality)  # 唐# 修改(没有改变量则会新增)
# 只能通过类型名称修改:类名.类属性变量 = 数据
Person.nationality = "大唐"
print(Person.nationality)  # 大唐
print(emperor.nationality)  # 大唐 # 实例中的类属性也被修改# 对象实例属性扩展(避免此操作)
#   对象变量.类属性变量 = 数据
#   对象变量.新属性变量 = 数据#   以上两种方式只改变该对象中的数据,类属性没有被修改
emperor.nationality = "唐朝"
print(emperor.nationality)  # 唐朝(只是添加属性)
print(emperor_wife.nationality)  # 大唐  # 其他对象的类属性不会被修改
print(Person.nationality)  # 大唐  # 类属性没有被修改emperor.country = "唐朝"  # 只是新增和类属性值相等的对象属性,不修改原来类属性
print(emperor.country)  # 唐朝
print(Person.nationality)  # 大唐# print(emperor_wife.country)  # 没有该属性,会报错
# print(Person.country)  # 没有该属性,会报错emperor.entertainment.append("惊破《霓裳羽衣曲》")  # 实例中修改可变类型中的数据
print(Person.entertainment)  # ['渔阳鼙鼓动地来', '惊破《霓裳羽衣曲》']  # 类属性也实际被修改
emperor.entertainment = ["缓歌慢舞凝丝竹", "尽日君王看不足"]   # 实例给可变类型重新赋值
print(Person.entertainment)  # ['渔阳鼙鼓动地来', '惊破《霓裳羽衣曲》']  # 只是给实例对象添加属性,类属性没有被修改

5 魔术方法

魔术方法是类型中从object继承(继承见下一篇文章)过来的,使用双下划线开头和结尾,具有特殊功能的方法

5.1 对象的打印: __str__()和__repr__()

  • 对象一旦创建完成,是将对象在内存中的地址临时存储在引用变量中的通过引用变量才能访问到对象
  • 在程序中print()直接打印可以找到对象的引用变量时,就会得到引用变量中存储的内存地址数据
  • __str__(self)方法,用于 print()直接打印对象时展示自定义数据
  • 但当对象包含在组合数据类型中时,直接打印数据类型,此时的对象又会变成了内存地址的形式
  • __repr__(self)方法,用于当对象包含在组合数据类型中时,按照自定义的方式展示对象的数据
  • 两种方法返回的必须是字符串,不能是数字
  • 如果没有__str__()方法,会寻找执行__repr__()方法,有同样输出结果(无论对象是否在组合数据中)

直接打印前面创建好的对象,会得到地址:

print(emperor)  # <__main__.Person object at 0x000002B9BA53DC88>

在4的类定义的代码上,添加__str__(self)方法:

class Person:"""人的类型"""# 类属性nationality = "唐"# 初始属性,姓名,性别,身份,称呼def __init__(self, name, gender, position, nickname):  # 初始属性self.name = nameself.gender = genderself.position = positionself.nickname = nickname# __str__()方法:def __str__(self):"""对象打印的方法"""return f"这是对象实例 {self.name}"# 成长的行为def grow_up(self):print("杨家有女初长成,养在深闺人未识。")# 娱乐的行为def entertainment(self, item):if item == "drum":print("渔阳鼙鼓动地来")elif item == "dance":print("惊破《霓裳羽衣曲》")else:print("骊宫高处入青云,仙乐风飘处处闻")

再打印对象:

# 打印对象
print(emperor)  # 这是对象实例 李隆基
print(emperor_wife)  # 这是对象实例 杨玉环

此时如果对象在组合数据中,打印组数据又会显示内存地址:

lst = [emperor, emperor_wife]
print(lst)  # [<__main__.Person object at 0x000002C675DCDDC8>, <__main__.Person object at 0x000002C675E42108>]

继续上面类定义的代码上,添加__repr__(self)方法:

class Person:"""人的类型"""# 类属性nationality = "唐"# 初始属性,姓名,性别,身份,称呼def __init__(self, name, gender, position, nickname):  # 初始属性self.name = nameself.gender = genderself.position = positionself.nickname = nickname# __str__()方法:def __str__(self):"""对象打印的方法"""return f"这是对象实例 {self.name}"# __repr__()方法def __repr__(self):"""对象包含在组合数据类型中的打印方法"""return f"这是对象实例 {self.name}"# 成长的行为def grow_up(self):print("杨家有女初长成,养在深闺人未识。")# 娱乐的行为def entertainment(self, item):if item == "drum":print("渔阳鼙鼓动地来")elif item == "dance":print("惊破《霓裳羽衣曲》")else:print("骊宫高处入青云,仙乐风飘处处闻")

再次打印,则会按照自定义方式展示:

# 对象包含在组合数据类型中打印
lst = [emperor, emperor_wife]
print(lst)  # [这是对象实例 李隆基, 这是对象实例 杨玉环]

5.2 其他魔术方法

对象构建:

  • __new__(cls) 创建对象,(创建对象时)自动调用,定义类时一般不需要自己写
  • __init__ 初始化实例,给创建的对象赋值,(创建对象成功后)自动调用

对象打印:

  • __str__(self) 使用print(对象引用变量) 输出自定义字符串数据
  • __repr__(self) 当其他对象引用使用当前对象时(当对象包含在组合数据类型中
    时),打印展示自定义字符传数据

对象比较:

  • __cmp__(self, other) 大于 other 对象数返回1、等于 other 对象其他数返回0、小于 other 对象数返回-1(分别设置)
  • __gt__(self, other) 判断当前对象是否大于 other 对象
  • __lt__(self, other) 判断当前对象是否大于 other 对象
  • __ge__(self, other) 判断当前对象是否大于等于 other 对象
  • __le__(self, other) 判断当前对象是否大于 other 对象
  • __eq__(self, other) 判断当前对象是否等于 other 对象
  • __ne__(self, other) 判断当前对象是否不等于 other 对象

四则运算:

  • __add__(self, other) +
  • __sub__(self, other) -
  • __mul__(self, other) *
  • __divmod__(self, other) 获取整除结果和余数
  • __floordiv__(self, other) //, 下取整
  • __pow__(self, other) 幂运算**

增量运算:

  • __iadd__(self, other) +=
  • __isub__(self, other) -=
  • __imul__(self, other) *=
  • __idiv__(self, other) /=
  • __ifloordiv__(self, other) //=
  • __ipow__(self, other) **=

函数式调用:

  • __call__(self) 让对象可以类似函数的方式直接调用执行

对象删除:

  • __del__(self) 对象将要被删除的操作(执行删除命令,先执行里面的代码后再进行删除

查看属性:

  • __dict__() 查看属性(包括私有属性)

部分魔术方法举例:

class Person:"""人的类型"""# 初始属性def __init__(self, name, age):  # 初始属性self.name = nameself.age = agedef __le__(self, other):"""小于等于other返回结果"""if self.age <= other.age:return Truereturn Falsedef __cmp__(self, other):if self.age > other.age:return 1elif self.age < other.age:return -1else:return 0def __floordiv__(self, other):"""除法,向下取整"""return self.age // other.agedef __call__(self, *args, **kwargs):"""函数式调用"""print(args, kwargs)print(f"{self.name} 年龄 {self.age}")li = Person("李隆基", 52)
yang = Person("杨玉环", 18)print(li.__cmp__(yang))  # 1
print(li >= yang)  # True
print(li // yang)  # 2
yang("回眸一笑百媚生,六宫粉黛无颜色。")
# ('回眸一笑百媚生,六宫粉黛无颜色。',) {}
# 杨玉环 年龄 18

回眸一笑百媚生,六宫粉黛无颜色——python面向对象基础相关推荐

  1. Python面向对象基础(上)—Python Day7

    导入 --Python面向对象基础 Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. 面向对象 ...

  2. Python面向对象基础示例_创建对象

    Python面向对象基础示例_创建对象 python是面向对象的语言,你可以很轻松的创建一个类和对象.本书代码源自<<Python 3 Object-Oriented Programmin ...

  3. python面向对象基础-封装

    面向对象就是将编程当成一个事务,对外界来说,事务是直接使用,不用去管他内部的情况.而编程就是设置事务能够做什么事. 类 类是对一系列具有 相同特征和行为的事务的统称,是一个抽象的概念,不是真实存在的事 ...

  4. Python 面向对象 基础

    编程范式概述: 面向过程 和 面向对象 以及函数式编程 面向过程:(Procedure Oriented)是一种以事件为中心的编程思想. 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实 ...

  5. python面向对象基础_python面向对象基础

    面向对象基础 一.面向对象和面向过程 面向过程: 优点:复杂问题流程化,进而简单化 确定:可扩展性差 面向对象: 优点:可扩展性高 缺点:编写复杂度高于面向过程 二.类与对象 类即类别.种类,是面向对 ...

  6. python面向对象基础-01

    面向对象(OOP)基本概念 前言 话说三国时期曹军于官渡大败袁绍,酒席之间,曹操诗兴大发,吟道:喝酒唱歌,人生真爽! 众将直呼:"丞相好诗",于是命印刷工匠刻板印刷以流传天下;待工 ...

  7. python面向对象基础语言进阶

    在此感谢前辈们的指导:http://python.jobbole.com/80955/ https://www.cnblogs.com/wupeiqi/p/4766801.html https://w ...

  8. Pycharm设置开发模板/字体大小/背景颜色 - Python零基础入门教程

    目录 一.Pycharm 设置字体大小/风格 二.Pycharm 设置背景颜色 三.Pycharm 设置开发模板 四.猜你喜欢 零基础 Python 学习路线推荐 : Python 学习目录 > ...

  9. Python面向对象基础:编码细节和注意事项

    在前面,我用了3篇文章解释python的面向对象: 面向对象:从代码复用开始 面向对象:设置对象属性 类和对象的名称空间 本篇是第4篇,用一个完整的示例来解释面向对象的一些细节. 例子的模型是父类Em ...

最新文章

  1. 在同一台电脑上同时安装Python2和Python3
  2. linux 权限 x 表示,在Linux系统中,用户对目录拥有“x”权限,表示可以执行下列哪种操作?...
  3. 使用StateServer机制来解决session丢失而造成用户验证失败
  4. Java实现堆排序及详细图解
  5. 设置Tomcat字符编码UTF-8
  6. F-Principle:初探深度学习在计算数学的应用
  7. canvas rotate 累加旋转_高考数列通项公式解题方法(1):观察法、公式法、累加法、累乘法...
  8. 多个常见代码设计缺陷
  9. 1.3tf的varible\labelencoder
  10. c#读取指定字符后的字符_在C#中读取字符的不同方法
  11. 订阅号如何配置服务器信息,订阅号服务号区别和订阅号启动服务器配置
  12. Python 基础知识 D7
  13. VS软件设置中的宏定义
  14. 【VBA】Str与CStr辨析
  15. 从古至今的计算机设备,计算器从古至今的发展形成
  16. 什么样的用户标签系统,可以深入业务构建用户价值体系?
  17. matlab---s函数讲解之二连杆动力学仿真
  18. B站才是头条系的大敌
  19. 初级模拟电路:2-4 限幅器
  20. python批量剪辑音频pydub

热门文章

  1. UE5学习笔记——我为什么要学虚幻引擎
  2. 腾讯 SSL 免费证书申请步骤
  3. Linux系统云服务器查看/启用网站日志
  4. float和real的区别
  5. 热烈庆祝菏泽市牡丹区女企业家协会成立 太爱肽吴霞董事长当选第一届名誉会长
  6. UE4 报错 missing type specifier - int assumed
  7. 玩过这些经典单机游戏,就说明你已经老了
  8. 实用微带线的相关计算
  9. OpenCV高斯滤波GaussianBlur
  10. 前端js实现淘宝部分界面