先说一些废话,距离上次更新隔了九天,主要是自己假期时间要学车考驾照,所有每天只能抽一些支离破碎的时间用来学习,导致学习效率很慢(之前也说过了,本人是一个对学习有洁癖的人(含贬义 狗头))所以导致学的很慢,不过这些也可能是我的借口,七天学python终究没有坚持下来,本人张合hhhh,在此宣布计划失败,不过之后仍会保持更新,最后祝7月20日生日的小伙伴们生日快乐!(是不是很突兀hhhh,我也这样觉得,但我就想说一句生日快乐!)

面向对象

面向对象是一种抽象化的编程思想

类和对象

类和对象的关系:用类去创建一个对象 实例化

  1. 类是对一系列具体相同特征和行为的事物的统称,是一个抽象的概念,不是真实存在的事物

    特征即是属性,行为即是方法

    class 类名():....
    

    类名要满足标识符命名规则,同时遵循大驼峰命名习惯

  2. 对象

    对象是类创建处理的真实存在的事物

    先有类,再有对象

    对象名 = 类名()
    
    # 定义类
    class Dog():# 模拟小狗的测试def __init__(self, name, age):# 初始化属性name和ageself.name = name   # 访问对象属性   初始化属性self.age = ageprint(self)    # <__main__.Dog object at 0x0000016AED023010>def sit(self):"模拟小狗蹲下"print(self.name.title() + " is now sitting")# 创建对象/实例化对象
    my_dog = Dog('willie', 6)# 访问属性
    print("my dog's name is " + my_dog.name.title())   # my dog's name is Willie
    print("my dog is " + str(my_dog.age) + ' years old')   # my dog is 6 years old
    # 调用方法
    print(my_dog.sit())   # Willie is now sittingprint(my_dog)   # <__main__.Dog object at 0x0000016AED023010>
    # 对象和self得到的内存地址相同,所以self指的是调用该函数的对象
    

    类中的函数称为方法,类的方法与函数并无区别,所以仍可使用位置参数、默认参数、可变参数、关键字参数

    其中,__ init _ _()是一个特殊的方法,每当根据类创建实例时,python会自动运行。该方法的名称中,开头和末尾各有两个下划线,这是一种约定,旨在避免python默认方法与普通方法发生名称冲突

    self是一个指向实例本身的引用,让实例能够访问类中的属性和方法。创建实例时,将自动传入实参self,每个与类相关联的方法调用都自动传递实参self。self会自动传递,因此不需要传递它。

    对象属性既可以在类外面添加和获取,也可以在类里面添加和获取。

    类外面添加对象属性 语法:对象名.属性名=值

    类外面获取对象属性 语法:对象名.属性名

    类里面获取对象属性 语法:self.属性名

    要访问实例的属性、调用方法时,可使用句点表示法。即指定实例的名称和要调用的方法和访问的属性,并用句点分隔。即my_dog.name my_dog.age my_dog.sit()

    一个类可以创建多个对象

魔法方法

在python中,__xx__的函数叫做魔法方法,指的是具体特殊功能的函数

__init__()

作用:初始化对象

注意:

  1. __init__()方法,在创建一个对象时默认被调用,不需要手动调用
  2. __init__(self)中self参数,不需要传递,python解释器会自动把当前的对象引用传递过去
  3. 由于创建对象时__init__()会默认被调用,所以有__init__()创建对象时,不能传入空的参数,必须传入与__init__()匹配的参数
# 魔法方法
'''
1. 定义类init魔法方法
2. 创建对象
3. 验证'''# 定义类
class Washer():def __init__(self):# 添加实例属性self.width = 500self.heigth = 800def print_info(self):# 调用实例属性print(f'洗衣机的宽度是{self.width},洗衣机的高度是{self.heigth}')# 创建对象
haier = Washer()haier.print_info()  # 洗衣机的宽度是500,洗衣机的高度是800# 不需调用init函数便可直接运行,说明init函数已在创建对象时默认运行,不需要手动调用
# 带参数的init
class Washer():def __init__(self,width,heigth):# 添加实例属性self.width = widthself.heigth = heigthdef print_info(self):# 调用实例属性print(f'洗衣机的宽度是{self.width},洗衣机的高度是{self.heigth}')# 创建对象
haier = Washer(10,20)haier.print_info()   # 洗衣机的宽度是10,洗衣机的高度是20geli = Washer(50,30)geli.print_info()    # 洗衣机的宽度是50,洗衣机的高度是30
__str()__

当使用print输出对象的时候,默认打印对象的内存地址。如果类定义__str__方法,就会打印在这个方法中return的数据

# __str__
class Washer():def __init__(self,width,heigth):self.width = widthself.heigth = heigthdef __str__(self):return '海尔洗衣机'haier = Washer(20,10)print(haier)   # 海尔洗衣机
__del()__

当删除对象时,python解释器会默认调用__del__()方法

# __del__
class Washer():def __init__(self,width,heigth):self.width = widthself.heigth = heigthdef __str__(self):return '海尔洗衣机'def __del__(self):print(f'{self}已被删除')haier = Washer(10,20)# del haier
# 海尔洗衣机对象已被删除
# 不用手动删除,del同样会被调用  当代码运行完,内存释放,对象会被删除,所以del会被自动调用

继承

继承是一种创建新类的方式,新建的类可称为子类或派生类,父类可称为基类或超类

python面向对象的继承指的是各个类之间的所属关系,即子类默认继承父类的所有属性和方法

python支持多继承,新建的类可以支持一个或多个父类

# 定义父类
class A():def __init__(self):self.num = 1def pri_info(self):print(self.num)# 定义子类
class B(A):pass# 查看父类默认继承的类
print(A.__bases__)   # (<class 'object'>,)   python3中默认继承object类
# 查看子类B继承的父类
print(B.__bases__)   # (<class '__main__.A'>,)# 测试
result = B()
result.pri_info()   # 1  说明子类会继承父类的全部属性和方法
经典类与新式类

python2有经典类与新式类的区别:

经典类:没有继承object类的子类,以及该子类的子类、子子类。不由任意内置类型派生出的类

新式类:继承object类的子类,以及该子类的子类、子子类

class 类名:代码    # 经典类class 类名(object):代码    # 新式类

在python3中,没有继承任何类,默认继承object类,object类是所有类的顶级类,所以python3中都是新式类

单继承
class Animal():def run(self):print('Animal is running')class Cat(Animal):passcat1 = Cat()
cat1.run()   # Animal is running
多继承

多继承即一个类可同时继承多个父类

class A():def print_info(self):print('A')class B():def print_info(self):print('B')class C(A, B):pass# 查看C的父类
print(C.__bases__)   # (<class '__main__.A'>, <class '__main__.B'>)
# A和B都是C的父类c1 = C()
c1.print_info()   # A
# 当一个类中有多个父类时,默认优先使用第一个父类的同名属性和方法

注意:当一个类有多个父类时,默认使用第一个父类的同名属性和方法

多层继承

python支持多层继承

class A:pass
class B(A):pass
class C(B):pass
继承的查找顺序

对象->子类->直接父类->间接父类

class Foo():def f1(self):print('Foo.f1')def f2(self):print('Foo.f2')self.f1()class Bar(Foo):def f1(self):print('Bar.f1')obj = Bar()
obj.f2()
'''
结果:
Foo.f2
Bar.f1
'''
多继实现原理(mro顺序)
  1. 菱形结构

    D继承B和C,B和C分别继承A,这就是一个菱形结构

    如果属性或方法重名,输出的顺序是按mro列表输出的顺序继承

    class A():def test(self):print('A')class B(A):def test(self):print('B')class C(A):def test(self):print('from C')class D(B,C):passobj = D()
    obj.test() # 结果----> B
    ''' 可以打印出mro列表查看顺序'''
    print(D.__mro__)
    # (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
    

    注意:

    1.__mro__也可写成mro(),即类名.mro()。前者返回一个元组,而后者返回一个列表。调用mro方法必须是起始类

    2.mro通过一个C3线性算法实现

    3.mro查找准则:1.先查子类,再查父类2.当继承多个父类时,按mro列表顺序查找

  2. 非菱形结构

    class E:passclass F:passclass B(E):passclass C(F):passclass D:def test(self):print('D')class A(B, C, D):passprint(A.__mro__)
    # (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class 'object'>)obj = A()
    obj.test()   # D
    

    经典类按深度优先算法查询

    新式类按广度优先算法查询

子类重写父类同名属性和方法

子类和父类拥有同名属性和方法,子类创建对象调用时,调用的是子类的同名属性和方法

所以,当对于父类的方法,子类并不需要时,可对其进行重写,在子类中定义与要重写的父类方法同名。这样,python将不会考虑父类方法,而只关注子类中定义的相应方法。

super()调用父类方法

super()方法就是为了解决多重继承的问题,在一个父类中使用super()方法用来调用下一个父类的方法

super()方法有两种写法:1.super(当前类名,self).函数名() 2. super().函数()

class A():def test(self):print('A')class B(A):def test(self):print('B')super().test()class C(B):def test(self):super().test()c1 = C()
c1.test()
'''
结果为:
B
A
'''class A():def test(self):print('A')super().test()class B():def test(self):print('B')class C(A, B):passc1 = C()
c1.test()
'''
结果为:
A
B
'''
访问限制(私有属性和方法)

在class内部,可定义属性和方法,而外部代码可通过直接调用实例变量的方法来提取数据,这样就隐藏内部的复杂逻辑

python可为实例属性和方法设置私有权限,即设置某个实例属性或实例方法不继承给子类,或不被外部访问

设置私有权限的方法:在属性名和方法名 前面 加上两个下划线__

class A():def __init__(self):self.__name = '小明'self.age = 16def getname(self):   # 获取私有属性return  self.__namedef __getinfo(self):return '无法获取私有属性及方法'a = A()
print(a.age)   # 16
print(a.__name)   # 外部无法访问私有属性和私有方法
# 报错 AttributeError: 'A' object has no attribute '__name'. Did you mean: '_A__name'?
print(a.getname())   # 小明    可通过定义其他函数在内部获取私有属性
a.__getinfo()  # 报错 AttributeError: 'A' object has no attribute '__getinfo'. Did you mean: '_A__getinfo'?# 创建子类继承父类A
class B(A):pass
# 私有属性和方法不能被继承
b = B()
print(b.age)   # 16
print(b.__name)   # 报错    AttributeError: 'B' object has no attribute '__name'. Did you mean: '_A__name'?
# 并未继承到私有属性和私有方法
b.__getinfo()   # 报错

面向对象三大特性

  1. 封装

    即将属性和方法写到类的内部的操作即为封装

    封装可以为属性和方法添加私有权限

  2. 继承

    子类默认继承父类的所有属性和方法

    子类可以重写父类属性和方法

  3. 多态

    传入不同的对象,产生不同的结果

多态

多态指的是一类事物有多种形态(一个抽象类有多个子类,因此多态概念依赖于继承)

多态是一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果

class Animal():def run(self):print('Animal is running')class Dog(Animal):  # 子类重写父类方法def run(self):print('Dog is running')class Cat(Animal):   # 子类重写父类方法def run(self):print('Cat is running')def run_oneself(animal):     # 实例可用作属性,即将实例传入参数animal.run()# 两种写法
a = Dog()
# 第一种
run_oneself(a)   # Dog is running
# 第二种
run_oneself(Cat())   # Cat is running
run_oneself(Animal())   # Animal is running
# 传入不同的实例,执行的结果也不同

类属性和实例属性

类属性

类属性是类对象所拥有的属性,它被该类的所有实例对象所共有

类属性可以使用类对象或实例对象访问

类属性只能通过类对象修改,不能通过实例对象修改,如果通过实例对象修改类属性,表示的是创建一个实例属性

类属性的优点

记录的某项数据始终保持一致时,则定义类属性

实例属性要求每个对象为其单独开辟一份内存空间记录数据,而类属性为全类所共有,仅占用一份内存,节省内存空间

class A():# 设置类属性num = 10a1 = A()
a2 = A()# 访问类属性
print(A.num)  # 10
print(a1.num)  # 10
print(a2.num)  # 10# 修改类属性
A.num = 14
print(A.num)   # 14
print(a1.num)   # 14
print(a2.num)   # 14a1.num = 20
print(A.num)   # 14
print(a1.num)   # 20
print(a2.num)   #14
# 不能通过实例修改类属性,如果这样操作,实则是创建一个实例属性

类方法和静态方法

  1. 类方法

    需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数

    当方法中需要使用类对象(如访问私有类属性等时,定义类方法)

    类方法一般和类属性配合使用

    class A():__a = 10@classmethoddef get__a(cls):return cls.__aa = A()
    result = a.get__a()
    print(result)   # 10
    
  2. 静态方法

    需要通过装饰器staticmethod来进行修饰,静态方法既不需要传递类,也不需要传递实例对象(形参没有self/cls)

    静态方法能够通过实例对象和类对象去访问

    当方法中既不需要使用实例对象、也不需要使用类对象时,定义静态方法

    取消不需要的参数传递,有利于减少不必要的内存占用和性能消耗

    class A():@staticmethoddef info_print():print('A')a = A()
    # 静态方法既可以使用对象访问又可以使用类访问
    a.info_print()   # A
    A.info_print()   # A
    

常用方法总结

方法名称 功能
sel.__class__ 查看对象所属类
类名/对象名.__dict__ 查看类/对象名称空间
类名/对象名.__bases__ 查看父类
起始类名.__mro__ 打印继承顺序
locals() 查看局部名称空间
globals() 查看全局名称空间
dirs(str) 查看字符串所搭配的内置方法有哪些,查看内容可换

一周学python系列(7)——面向对象相关推荐

  1. df满足条件的值修改_文科生学 Python 系列 16:泰坦尼克数据 2(缺失值处理)

    第八课:案例分析 - 泰坦尼克数据 本节课将重点分析泰坦尼克号沉船事故,我们将探索是什么因素决定了最后是否生还. 我们将将前面课程所学过的知识点融会贯通,举一反三 新增知识点: 缺失值处理:panda ...

  2. 文科生学python系列_文科生学 Python 系列 3:函数

    文科生学Python系列3:函数​www.jianshu.com 还是第二课的内容 函数是一段可以重复使用的代码,往往是为了解决某个特定的人物.在 Python 中有两种函数:内置函数和自定义函数. ...

  3. 从源代码学Python系列目录

    Hello,我是 Alex 007,一个热爱计算机编程和硬件设计的小白,为啥是007呢?因为叫 Alex 的人太多了,再加上每天007的生活,Alex 007就诞生了. 从源代码学Python系列 第 ...

  4. python能开发什么产品_三周学 Python ?不,三周做个产品

    我的同事在看到毫无开发经验的我用三周时间,不但从零基础用上了 Python,还做出了一个客户关系管理系统,强烈邀请我分享经验.惶恐,因为我并没有出色的智商,也没有觉得三周学 Python 是一个体现自 ...

  5. 免费视频教程!零基础学Python系列(7) - 数据类型之bytes(上)

    本节我们开始讲python数据类型之bytes类型,我们分为上下两个章节. 你可以直接到这个页面观看本节视频:免费视频教程!零基础学Python系列(7) - 数据类型之bytes(上) 以下为对应的 ...

  6. microbit python_刘鹏涛老师用Microbit 学Python系列教程

    本帖最后由 rzyzzxw 于 2018-4-5 11:33 编辑 刘鹏涛老师Microbit 学Python系列教程 经刘老师授权,刘老师订阅号刘鹏涛 捕获.PNG (6.22 KB, 下载次数: ...

  7. c语言随机生成整数存放一维数组_文科生学 Python 系列 7: Numpy 数组/索引和切片...

    第四课:本课内容: • 0. 导入 NumPy 包 • 1. 创建 NumPy 数组 • 2. 索引和切片 • 3. 读取文件 • 4. 布尔型索引 • 5. 数组的运算 • 6. 常用函数举例 Nu ...

  8. 五分钟学会python_关于五分钟学Python系列视频

    Up主记得我们父母辈考大学的时候,外语,尤其是英语,是一个非常火爆的专业.那个时候会英语的人相对比较少,因此能掌握流利的英文听说读写的学生可以算是稀缺人才.现在虽然英语专业人才仍然有很大市场,但是整体 ...

  9. 【循序渐进学Python】7.面向对象的核心——类型(上)

    我们知道Python是一门面向对象的脚本语言.从C#的角度来看:首先Python支持多继承.Python 类型成员通常都是public的,并且所有成员函数都是virtual的(可以直接重写). 1. ...

最新文章

  1. 【翻译】Programming Ruby——正则表达式
  2. ThinkPHP模板之二
  3. 【opencv4】opencv视频教程 C++(opencv教程)2、加载imread()(以灰度加载),修改,保存图像
  4. drop by time at xjtlu consultation center
  5. 有关替换字符的代码问题
  6. python新手入门项目推荐_推荐:一个适合于Python新手的入门练手项目
  7. XML DOM Object Model in .NET [2/3]
  8. 记录阿里技术面试全流程
  9. jsp+ssm计算机毕业设计学校缴费系统【附源码】
  10. 计算机恢复语言文件格式,txt文件乱码怎么恢复正常
  11. 20090522: IBM X22
  12. python为啥爬取数据会有重复_使用python爬取B站千万级数据
  13. 树莓派hwclock命令参数及用法详解--linux显示/设置硬件时钟命令
  14. 【LeetCode】322. 零钱兑换 结题报告 (C++)
  15. 北大学子求职经历与建议(IT类)
  16. 中山LED芯片IC方案!JLC1041, JLK105系列两款超实用
  17. 30、OAK摄像头使用官方的yolox进行初训练和测试
  18. 论文阅读:CTF:Anomaly Detection in High-Dimensional Time Series with Coarse-to-Fine Model Transfer
  19. 快速上手Matlab二维画图
  20. word题注编号格式从仅数字顺序编号到包含章节号编号

热门文章

  1. 使用C#.NET WebBrowser控件导航到不同的网站出现 所请求的资源正在使用中。 (从HRESULT异常:0x800700AA)
  2. Ubuntu 16.04 LTS安装搜狗输入法解析
  3. cocos2d - 触摸事件
  4. 帝国php漏洞,帝国CMS(EmpireCMS) v7.5 后台XSS漏洞分析
  5. 学生成绩录入案例----python基础入门
  6. 关于Numpy数组中属性shape的理解
  7. MATLAB遗传算法工具箱安装包及安装方法(图解)
  8. 【三十五】Python全栈之路--MySQL
  9. uni-app获取当前位置并计算出某个地点距离
  10. 云南大学计算机在职硕士,云南大学信息学院硕士研究生教育