文章目录

  • 类和对象
    • 面向对象概述
      • 对象
      • 面向对象程序设计的特点
    • 类的定义和使用
      • 定义类
      • 创建类的实例(创建对象)
      • 命名空间
      • 魔术方法
      • 创建类的成员并访问
      • 访问限制
    • 属性
      • 创建用于计算的属性
      • 为属性添加安全保护机制
    • 类与类之间的关系
      • 依赖(关联)
      • 组合(聚合)
      • 继承(实现)
        • 继承的基本语法
        • 淇淇的进阶课堂
        • 方法重写
        • 派生类中调用基类的方法
        • 淇淇的进阶课堂
      • 多继承和多重继承的区别
      • 补充内容`isinstance()及issubclass() `
      • super
    • 封装性
      • 栈:先进后出
      • 队列:先进先出
        • 淇淇的进阶课堂
      • 封装的定义
        • 私有属性
        • 私有方法
      • 破解私有属性
    • 多态性
      • 多态
      • 多态性
    • 设计模式
      • 单例模式
        • 实现单例模式的几种方式
      • 工厂模式
    • 约束
      • 约束的定义
    • 实例方法
    • 类方法
    • 静态方法
      • property
    • 反射.
    • 内置方法
    • 异常机制

类和对象

面向对象概述

什么叫做面向对象?

​ 所谓的面向对象其实就是把属性和方法封装起来,以供重复调用。

比如人:

​ 人的属性:姓名,年龄,性别

​ 人的方法:唱,跳,rap

之前我们没有学习面向对象的时候会这样定义:

伪代码:

姓名 = “帅帅”
年龄 = 18
性别 = “superman”
def 唱():print(“唱的真好听”)
def 跳():print("跳的真好看")
def rap():print("rap世界第一")

这样写有一个弊端,就是只有帅帅,淇淇不服啊。为什么她不出来一下?那么下面我们在实现淇淇的伪代码:

姓名 = “淇淇”
年龄 = 18
性别 = “girl”
def 唱():print(“唱的真好听”)
def 跳():print("跳的真好看")
def rap():print("rap世界第一")

这个时候淇淇的伪代码就完成了,但是淇淇在某些方面是不如帅帅的,这个时候我们要把函数给重新架构一下,成下面这样:

伪代码:

姓名 = “淇淇”
年龄 = 18
性别 = “girl”
def 唱():print(“唱的没帅帅真好听”)
def 跳():print("跳的没帅帅好看")
def rap():print("rap世界第二,搁帅帅后面排着")

到此,我们写完了两个人的,那么如果我们要写很多人呢?这个时候是不是可以把他们给抽象出来,变成一张图纸一样,用的时候直接拿过来用就可以?我们尝试着写成以下的伪代码:

伪代码:

人:属性:姓名年龄性别方法:唱跳rap

这个时候我们发现,只要是人,就可以拥有着写属性和方法。那么这个时候我们可以造出很多这样的人,比如薛之谦,王一博,周杰伦,他们有个共同的特征就是拥有人的属性和方法。

那么在python里面我们是怎样解决的呢?且看我把上面的伪代码实现

class Person:def __init__(self,name,age,sex):self.name = nameself.age = ageself.sex = sexdef sing(self):print(f"{self.name}唱的真好听")def dump(self):print(f"{self.name}跳的真不错")def rap(self):print(f"{self.name}世界第一")

这个时候我们肯定很奇怪,这不就是把之前的属性和方法前面套了一个class嘛,有什么神奇的?

下面我带你见证这一神奇的时刻:

shuaishuai = Person("帅帅",18,"superman")
shuaishuai.sing()
shuaishuai.dump()
shuaishuai.rap()
#结果:
帅帅唱的真好听
帅帅跳的真不错
帅帅世界第一

到这是不是还是有些不服,这上面的代码完全可以实现,我这写的都多了,是不是?

那么我们在把淇淇也写出来:

qiqi = Person("淇淇",18,"beautifulgirl")
qiqi.sing()
qiqi.dump()
qiqi.rap()
#结果
淇淇唱的真好听
淇淇跳的真不错
淇淇世界第一

这个时候是不是也没多少感觉,只是减少了一点点代码而已啦,那么接下来就是见证帅帅有多帅的时刻了:

zhoujielun = Person("周杰伦",28,"man")
wangyibo = Person("王一博",21,"man")
xuezhiqian = Person("薛之谦",32,"man")
linjunjie = Person("林俊杰",25,"man")

连续生成四个人,而且他们四个人都可以进行唱,跳,rap

你要用以前的方式写,现在都好几十行了,而我这,短短的四行。

这就是面向对象的魅力

对象

什么叫做对象呢?

​ 这道题就是送分题,你的女朋友或者你的男朋友。这里有个狗粮,帅帅&淇淇。单身狗看我博客是不是特别心酸?

​ 开个玩笑,对象就是实际生活中具体的事物。比如你的车就是一个对象,你的小狗就是一个对象,我的手机也是一个对象。我手机老破了,太难过。

python中一切皆对象,linux中一切皆文件

淇淇的进阶课堂:判断下面那个是对象

我的电脑

你的电脑

电脑

鼠标

键盘

手机

我的自行车

Alex的特斯拉

我假装有个特斯拉

什么叫做类?

类是封装对象的属性和行为的载体

类是对象的抽象。刚才我们说了对象就是具体的事物。那么比如我的车,你的车都是对象,这个时候他们有个统一的标准,比如四个轮胎,一个方向盘,四个座椅。而这个时候我们说车的时候,就会知道他会有我们所说的那些属性和方法。

我们住的房子,他就是对象,但是设计房子的图纸,他就是类。他可以设计成各种各样的,然后由我们勤劳的劳动人民去实现。比如天津的网红图书馆,天津的失恋博物馆(好像在这说这个有点尴尬,毕竟俺是有对象的人)。

那么我们刚才说的什么馆,抽象出他们的相同点,他们统一有一个专有名词,叫做馆。这个就是类。

总结:类是对象的抽象,对象是类的具体实例。

面向对象程序设计的特点

面向对象的三大特性:封装,继承,多态

封装:

我们使用电视遥控器,只需要知道按上下就可以进行换台操作,而不知道遥控器是具体怎么实现的,这就是封装。所谓封装,就是把具体实现隐藏起来,别人使用的时候只给固定的结构进行调用。

继承:

继承跟我们现实生活中的继承类似,你爸有好几套房,看你长大了,老在外面租房住,感觉不太好,送了你一套。这就是继承,而面向对象的继承比现实生活中强了不知道无数倍。继承来的东西你的父类还是存在。也就是说,你爸有十套房,你继承之后你也会有十套房,而且你爸还不会少。不像我们现实世界,你爸给你之后,你爸就没了这十套房。

多态:

一种事物的不同表现形态。python中是非常喜欢鸭子模型的,就是有个鸟,它会游泳,它会跑,它会叫,它就是鸭子。关于多态请看后面的多态详细描述。

类的定义和使用

类表示具有相同属性和方法的集合,使用类就是创建对象。

定义类

固定结构:

class 类名:  #类名一般使用大驼峰命名类属性类方法

写好了类之后并不能直接使用。就跟房子的图纸一样,你写好并不能进行住,需要盖好才可以。

创建类的实例(创建对象)

class Person:def __init__(self,name,age,sex): #self:代表当前对象 剩下的三个属性在类创建对象的时候必须实现#类属性,可以在__init__中添加,也可以在其他方法里面添加self.name = nameself.age = ageself.sex = sex#类方法def sing(self):print(f"{self.name}唱的真好听")def dump(self):print(f"{self.name}跳的真不错")def rap(self):print(f"{self.name}世界第一")shuaishuai = Person("帅帅",18,"superman")

删除对象属性:del 对象名.属性名不建议删除

__init__魔术方法

当类中写了这个方法的时候,第一个参数必须是self,代表当前对象,然后第二个参数开始就随意,但是这些参数在创建对象的时候必须一一实现。

创建对象的时候自动调用__init__方法

命名空间

类空间和对象空间

类也遵从自上而上执行,所以如果类里面有同名的方法,前一个方法会被后一个方法覆盖。

然后对象初始化的时候,会调用类覆盖好的方法

# 创建一个类,能够自动统计当前类创建了多少个对象
class Person():num = 0def __init__(self):Person.num += 1
print(Person.num)
Person()
Person()
Person()
Person()
print(Person.num)

魔术方法

python中前后用两个下划线包起来的叫做魔术方法

python3中的魔术方法有:

常用的魔术方法:
__init__:
1.用来构造初始化函数,用来给对象进行初始化属性,所以不需要返回值
2.创建对象的时候自动调用
3.自定义类如果不定义的话,默认调用父类object的,同理继承也是,子类若无,调用父类的,若有,调用自己的class Animal:def __init__(self):print("init初始化方法,没有调用父类object")Animal()
#结果:
init初始化方法,没有调用父类object__new__:
1.用所给类创建一个对象,并且返回这个对象
2.因为是给类创建实例,所以至少传一个参数cls,参数cls代表代表要实例化的类,此参数在实例化时用python解释器自动提供
3.在类实例化时内部创建类实例的函数,并且返回这个实例,所以它是实例时最先被调用的方法,一般不要人为定义该方法
4.因为要创建实例返回实例,所以要有返回值。return父类__new__出来的实例,或者直接是object的__new__出来的实例__class____delattr__
__dict__
__dir__
__doc__
__eq__
__format__
__ge__
__getattribute__
__gt__
__hash__
__init__
__init_subclass__
__le__
__lt__
__module__
__ne__
__new__
__reduce__
__reduce_ex__
__repr__
__setattr__
__sizeof__
__str__
__subclasshook__
__weakref__

创建类的成员并访问

类的成员主要有属性和方法,属性可以随意,方法的第一个参数必须是self

class Person:def __init__(self,name,age,sex):self.name = nameself.age = ageself.sex = sexdef sing(self):print(f"{self.name}唱的真好听")def dump(self):print(f"{self.name}跳的真不错")def rap(self):print(f"{self.name}世界第一")shuaishuai = Person("帅帅",18,"superman") #初始化
#访问成员方法
shuaishuai.sing()
shuaishuai.dump()
shuaishuai.rap()

访问类中的属性和方法只需要对象使用成员运算符来进行调用

类属性通过类来访问,对象属性通过对象来访问

访问限制

如果想把某些属性给隐藏起来,不想让外界直接访问,可以在属性名前面加两个下划线。比如帅帅不想直接让别人知道他的年龄或者修改他的年龄:

可以使用单下划线,双下划线,首尾双下划线来限制访问权限

单下划线开头的是protected类型的成员,只允许类本身和子类进行访问,不能使用from xxx import ccc进行导入

双下划线只能由定义了该属性或方法的类调用,而不能由类的对象调用,类的对象如果想调用,必须使用set/get方法

首尾双下划线是系统定义的特殊方法,一般是系统定义的名字

class Person:def __init__(self, name,sex):self.name = nameself.__age = Noneself.sex = sexdef set(self,age):self.__age = agedef get(self):return self.__agedef sing(self):print(f"{self.name}唱的真好听")def dump(self):print(f"{self.name}跳的真不错")def rap(self):print(f"{self.name}世界第一")shuaishuai = Person("帅帅","superman")  # 初始化
#这个时候初始化帅帅的年龄就会报错,可以使用set方法来赋值,get方法取值
shuaishuai.set(18)
print(shuaishuai.get())

属性

创建用于计算的属性

有的时候我们需要创建对象的时候就进行给属性赋值,但是这样的方法往往是不安全的,会直接修改我们类中的属性,这样的话安全性不高。比如你的年龄是18岁,但是这个时候有用户进行恶作剧,直接将其修改为600岁,你是不是乐坏了?但是你感觉现实吗?

python中使用@property将一个方法转换为属性,从而实现用于计算的属性,将方法转换为属性后,可以直接通过方法名来访问,而不需要加括号。

class Person:def __init__(self,name,age):self.name = nameself.age = age@propertydef func(self):if self.age < 150 and self.age > 0:print(self.age)else:print("想啥呢?")shuaishuai = Person("帅帅",18)
shuaishuai.func  #func这个属性不能对其赋值,因为他本质也是一个函数

@property可以将属性设置为只读属性

为属性添加安全保护机制

为此,python中有了私有属性和私有方法供大家使用。私有属性就是在属性前面加两个下划线,然后给这个私有属性给予set和get方法,这样对象调用的时候就只能通过set方法来进行赋值,get方法来获取值

class Person:def __init__(self, name,sex):self.name = nameself.__age = Noneself.sex = sexdef set(self,age):self.__age = agedef get(self):return self.__age

类与类之间的关系

一个一个的类就跟我们现实世界中的模板一样,只有把他们全部关联起来,才会使我们做事更加高效。比如轮胎跟发动机组合成了车,零食跟零食袋组合成了零食一样。类和类的组合,一般分为以下三种关系:

依赖(关联)

一个动作执行的时候,需要另一个动作来帮忙。比如打开电脑,帅帅去玩电脑或者帅帅去打王者

依赖就是我用你,你需要我。

比如帅帅玩电脑,电脑需要帅帅玩

#依赖
class Person:def run(self):print("我没事干")class Computer:def play(self,tool):tool.run()print("我是电脑,玩我")class Phone:def play(self,tool):tool.run()print("我有王者荣耀,来玩啊")shuaishuai = Person()
dnf = Computer()
dnf.play(shuaishuai)   #依赖是给一个类的对象的方法给另一个对象wangzhe = Phone()
wangzhe.play(shuaishuai)

一个类使用某个类中的某个方法

这种情况下,类与类之间的关系是最轻的,可以随时替换。

依赖就是一个类的对象的方法自己完不成一些功能,需要另一个对象来完成,把他加载到此方法中。就是依赖

组合(聚合)

一个类需要某个类的具体对象去做一些事情,这就是组合。轮胎和发动机组合成了车一样。

组合可以一对一,也可以一对多

一个类与另一个类没有共同点,但是他们之间有关系,这就是组合

组合就是我需要什么,但是我没有这些东西,我就拿你。

class Car:def __init__(self,name,power = None):self.__name = nameself.__power = powerdef set_power(self,power):self.__power = powerdef zhuang_Tread(self):print(f"{self.__name}装好了{self.__power.get_name()}的轮胎")def saiche_power(self):print(f"{self.__name}装好了{self.__power.get_name()}的发动机")class Tread:def __init__(self,name):self.__name = namedef set_name(self,name):self.__name = namedef get_name(self):return self.__nameclass Engine:def __init__(self,name):self.__name = namedef set_name(self,name):self.__name = namedef get_name(self):return self.__nametread = Tread("牛逼牌")
engine = Engine("赛车")
car = Car("奔驰",tread)
car.zhuang_Tread()
car.set_power(engine)
car.saiche_power()#分析:
是不是发现了有很多的重复代码,而且极其麻烦,不如用继承好。刚开始用,还是没有那么的得心应手,我还的努力。

将一个类的对象封装到另一个类的属性中进行一些操作

淇淇的进阶课堂

老师和学生模型(老师对学生是一对多,学生对老师是一对一)
创建教师类和学生类
教师类有姓名和学生列表两个属性
教师类有添加学生的方法(添加的学生是具体对象)
教师类有显示对应学生姓名和学号的方法
学生类有学号/姓名/年龄属性
创建多个学生,并添加到某位教师的学生列表中
打印该教师的所有学生学号

继承(实现)

一般我们看到继承这两个字都有一种一夜暴富的心态。比如我们看的西虹市首富,猛虫过江,都是有了巨额的财富,令继承人过上了幸福的生活。那么在我们的Python中,继承究竟是怎么样的呢?在python中子类会拥有父类的属性和方法,但是不会继承私有属性和私有方法。被继承的类叫父类或基类,继承的类叫做子类或派生类。

继承的基本语法

#固定结构:
#父类
class Person(object): #括号里面写要继承的类def __init__(self, name,sex):self.name = nameself.__age = Noneself.sex = sexdef set(self,age):self.__age = agedef get(self):return self.__agedef sing(self):print(f"{self.name}唱的真好听")def dump(self):print(f"{self.name}跳的真不错")def rap(self):print(f"{self.name}世界第一")#子类
class Boy(Person):passshuaishuai = Boy("帅帅","superman")
shuaishuai.sing()#结论:
可以看出,子类Boy什么都没有写,只是继承了一下父类Person,他就拥有了父类的属性和方法,但是私有属性没有被继承。

淇淇的进阶课堂

老师和学生模型(老师对学生是一对多,学生对老师是一对一)
创建教师类和学生类
教师类有姓名和学生列表两个属性
教师类有添加学生的方法(添加的学生是具体对象)
教师类有显示对应学生姓名和学号的方法
学生类有学号/姓名/年龄属性
创建多个学生,并添加到某位教师的学生列表中
打印该教师的所有学生学号

组合是指在新类里面创建原有类的对象,重复利用已有类的功能“has-a”关系

而继承允许设计人员根据其它类的实现来定义一个类的实现“is-a”关系

方法重写

方法重写就是子类继承父类的方法,然后把方法体进行重写。

比如父类是房子的图纸,因为每个人对美的定义不一样,你感觉你爸弄得这个图纸不适合你,你又不想重新弄。就把比如卧室进行重新设计一下,床啥的就不换了。这就是方法重写

class Person(object):def __init__(self, name):self.name = namedef sing(self):print(f"{self.name}唱的真好听")#子类
class Boy(Person):def sing(self):print(f"{self.name}最帅")shuaishuai = Boy("帅帅")
shuaishuai.sing()
#结果:帅帅最帅
这个时候我们可以发现,原来我们不重写sing方法的时候,他调用的是父类的sing方法,当我们在子类中进行重写之后,他显示的就是子类的方法。
由此可以得出查找顺序:对象调用某个属性或者方法的时候,会先在当前类中进行查找,如果找不到,就去他的父类对象今进行查找。

深度优先和广度优先

派生类中调用基类的方法

子类如果有自己的初始化属性,也就是有魔术方法__init__的时候,子类不会自动执行父类的方法,必须使用super来进行调用,获取父类的初始化属性

使用super关键字调用父类的方法

子类如果编写了自己的构造方法,但没有显式调用父类的构造方法,而父类构造函数初始化了一些属性,就会出现问题

解决方式:调用超类构造方法,或者使用super函数 super(当前类名, self).init()

super在Python3和python2中的区别:

Python3可以使用直接使用 super().xxx 代替 super(Class, self).xxx

super钻石继承

super的内核 mro方法:返回的是一个类的方法解析顺序表(顺序结构)
我们定义的每一个类,Python 会计算出一个方法解析顺序(Method Resolution Order, MRO)列表,这也是super在父类中查找成员的顺序,它是通过一个C3线性化算法来实现的我们可以使用下面的方式获得某个类的 MRO 列表
类名.mro() 或者 对象名.__class__.mro()

淇淇的进阶课堂

练习:
有一个动物类,猫狗两个类都继承了动物,动物类拥有动物的属性,定制猫狗类的个性属性动物都有吃的方法,动物在吃东西之后会打印自己的血量值和智力值,但是猫和狗吃的东西不一样猫狗在吃了食物之后,猫会增加血量值,狗会增加智力

多继承和多重继承的区别

多继承是子类不断的继承父类,依次类推,最后的孙子类拥有父类跟子类的方法

#多继承
class Person(object):def run(self):print("人会跑")class Boy(Person):def like_girl(self):print("男孩喜欢女孩子")class Girl(Boy):def like_boy(self):print("女孩子也喜欢男孩子")class Kid(Girl):def kids(self):print("孩子是男孩跟女孩的爱情结晶")kid = Kid()
kid.run()
kid.like_girl()
kid.like_boy()
kid.kids()#结果
人会跑
男孩喜欢女孩子
女孩子也喜欢男孩子
孩子是男孩跟女孩的爱情结晶

可以看出,多继承就是最后的一个类拥有上面的类的属性和方法(除了私有属性和私有方法)

多重继承逻辑不行的人就别看了。

补充内容isinstance()及issubclass()

isinstance()及issubclass()
isinstance() 用于检查实例类型:isinstance(对象,类型)
issubclass() 用于检查类继承:issubclass(子类,父类)

super

使用多继承,会涉及到查找顺序(MRO)、钻石继承等问题
钻石继承
单继承时 类名.init()的方式和super().init()方式没啥区别

但是使用 类名.init()的方式在钻石继承时会出现问题

super的内核 mro方法:返回的是一个类的方法解析顺序表(顺序结构)
我们定义的每一个类,Python 会计算出一个方法解析顺序(Method Resolution Order, MRO)列表,这也是super在父类中查找成员的顺序,它是通过一个C3线性化算法来实现的

我们可以使用下面的方式获得某个类的 MRO 列表
类名.mro() 或者 对象名.class.mro()

封装性

栈:先进后出

栈在内存中保存对象的引用

堆在内存中保存对象

总结:对象在栈中保存,在堆中被引用

队列:先进先出

淇淇的进阶课堂

实现栈和队列

封装的定义

封装就是把一个个的属性和方法隐藏起来,只留下具体的接口供下一个人使用

我们最常见的封装就是遥控器,你不需要知道遥控器是怎么装的,直接拿来开始换台就行。比如动物世界。

私有属性

私有属性就是在属性前面加get/set方法,然后再当前类中进行调用和实现,外界只能使用这个属性的set/get方法来操作他。而且不能被子类继承

私有方法

私有方法跟私有属性一样,在方法前面加两个下划线

破解私有属性和私有方法
_类名__属性

破解私有属性

破解私有属性和私有方法:
在名称前加上 _类名,即 _类名__名称(例如a._A__N)

其实加双下划线仅仅是一种变形操作
类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式

多态性

多态

一个变量可以有不同的数据类型

一个事物的不同表现形态,具体表现在比如狗,有柯基,二哈,还有淇淇(淇淇那么可爱,哈哈哈)

python天生支持多态

多态性

多态基础上,定义统一的接口。不同的类对象作为参数使用时,得到的结果不同

python著名的鸭子模型:

只要你会某一类功能,你就是一只鸭子。

比如会游泳,会飞,会跑,好了,你是鸭子,周黑鸭的鸭子。

对比:
多态强调的是:一类事物 不同的形态
多态性强调的是:同一操作,作用对象不同,表现出不同实现方式(只关心行为结果)
练习
创建汽车类(Car)含实例属性颜色red,对象方法run,功能是打印XX颜色小汽车在跑。
创建猫类(Cat)含实例属性名字name,对象方法run,功能是打印猫咪XX在跑。
实例化汽车类颜色为红色,实例化猫类,使用公共函数调用对象方法

设计模式

设计模式就是前人总结的经验,解决某一类问题的具体方法。比如我们肯定都做过算术题,知道首先做括号里面的,然后在做乘除,最后加减。还有我们的城市群落的形成,也是先盖新城,拉动经济,在弄旧改。所以我们学习设计模式之后,以后解决某一类问题,都不需要再重复造轮子。

单例模式

有时通过单一对象方便集中管理资源
单例模式是保证一个类仅有一个实例的设计模式

保证了在程序的不同位置都可以且仅可以取到同一个对象实例:如果实例不存在,会创建一个实例;如果已存在就会返回这个实例。

总结:某一个类只有一个对象,可以处处调用

学习的文章

实现单例模式的几种方式

  1. 使用模块

    1. python的模块是天然的单例模式,模块第一次导入时,会生成.pyc文件,第二次导入时,他只会加载.pyc文件,而不会再次执行模块代码。
  2. 使用装饰器

  3. 使用类

  4. 基于魔术方法new(***)

    当实例化一个对象时,是先执行了类的__new__方法(我们没写的时候默认调用object.__new__)然后再实例化类的__init__方法

    class Singleton(object):instance= Nonedef __new__(cls, *args, **kwargs):if not cls.instance:cls.instance = object.__new__(cls)return cls.instances1 = Singleton()
    s2 = Singleton()print("s1的地址:{},s2的地址:{}".format(id(s1), id(s2)))
    结果:
    s1的地址:1085113828968,s2的地址:1085113828968
    
  5. 基于metaclass方式实现

    1. 相关知识
    2. 实现单例模式

工厂模式

python中不需要创建类,创建子类来实现工厂模式,可以直接使用

class Factory(object): def get_person(self, name, gender='M'):if gender == 'M':return Male(name)if gender == 'F':return Female(name)

约束

约束的定义

约束就是一些约定,我们以后早晨八点来上课,晚上十点回家。这就是一种约束。在学校我们听老师的话,在家里听爸爸妈妈的话,在社会上听领导的话。什么时候不听话呢?就是你成了爷爷的时候,哈哈哈。现在既然咋们还没有是爷爷的时候,就按照规定来干。

  1. 在父类建立一种约束(通过抛出异常)

    class Animal():def eat(self):raise Exception("子类必须拥有eat方法")class Dog(Animal):def eat(self):print("dog eat")class Cat(Animal):def eat(self):print("cat eat")class Bir(Animal):def bireat(self):print("bir eat")def change(tool):tool.eat()dog = Dog()
    change(dog)
    bir = Bir()
    change(bir)
    
  2. 引入抽象类的概念

    from abc import ABCMeta,abstractmethod
    class Airer(metaclass=ABCMeta):@abstractmethoddef airfly(self):pass
    #结论:
    抽象类在父类中抽象完毕之后,必须在子类中重写,不然会报错。
    

实例方法

类中定义的普通方法

class Person:def func(self):pass
只有实例化之后才可以使用,接收的第一个参数一定为对象本身

类方法

指一个类中通过@classmethod修饰的方法

第一个参数必须是当前类的对象,该参数名一般约定为cls,通过它来传递类的属性和方法。
调用:实例对象和类对象都可以调用
类方法是将类本身作为对象进行操作的方法

通过使用类方法可以在不创建对象的时候直接进行操作。比如有的时候我们不想要实例化对象,而执行一些操作的时候,完全可以使用

应用场景:当一个方法中只涉及到静态属性的时候可以使用类方法(类方法用来修改类属性)

#使用类方法对商品进行统一打折
#分析:商场里面客户购买东西,打几折的时候,用户自己算往往不是很快,而且还很累,这个时候就需要直接计算出打折后的价格。客户只需要调用这个类方法就可以。
class Shop:def __init__(self,price):self.__price = price@propertydef func(self):return self.__price * 0.5s = Shop(100)
print(s.func)
print(Shop.func)#进阶版
class Shop:__discount = 1  #折扣价def __init__(self,name,price):self.__name = nameself.__price = price@propertydef discount_money(self):self.__discount = 0.5@propertydef finally_money(self):return self.__price * self.__discounts = Shop("橘子",5)
s.discount_money
print(s.finally_money)Shop("苹果",10)
Shop.discount_money
print(Shop.finally_money)#类方法进阶版
class Shop:__discount = 1  #折扣价def __init__(self,name,price):self.__name = nameself.__price = price@classmethoddef discount_money(cls,num):cls.__discount = num / 10@propertydef finally_money(self):return self.__price * self.__discounts = Shop("橘子",5)
s.discount_money(8)
print(s.finally_money)

类方法说了这么多,具体应用场景还是不太明确,还需要接着研究。

静态方法

使用@staticmethod修饰的方法

参数随意,没有selfcls参数

方法体中不能使用类或实例的任何属性和方法

实例对象和类对象都可以调用

静态方法是类中的函数,不需要使用实例。也就是说不需要进行实例化就可以调用

静态方法一般定义后就不需要再进行修改,用来写一些固定的操作

应用场景:一般是与类和对象无关的代码

#静态方法
class Person:@staticmethoddef func():print("""1.搞嘛?2.不知道3.先记下来吧4.记下来不知道应用场景5.我好累""")
Person.func()

property

使用property修饰的方法可以直接使用对象.方法名进行调用,不需要给方法加括号。

应用场景:商场打折,计算周长,面积等

一般具有三种访问方式:获取,修改,删除

只有在属性定义property后才能定义setter,deleter

方法一

class Foo:@propertydef AAA(self):print('get的时候运行我')@AAA.setterdef AAA(self,value):print('set的时候运行我')@AAA.deleterdef AAA(self):print('delete的时候运行我')

方法二

class Foo:def get_AAA(self):print('get的时候运行我啊')def set_AAA(self,value):print('set的时候运行我啊')def delete_AAA(self):print('delete的时候运行我啊')AAA=property(get_AAA,set_AAA,delete_AAA)
#内置property三个参数与get,set,delete一一对应

只有@property定义只读,加上@setter定义可读可写,加上@deleter定义可读可写可删除

反射.

反射是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力。用比喻来说,反射就是程序在运行的时候能够“观察”并且修改自己的行为。

python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

反射就是通过字符串的形式,导入模块;通过字符串的形式,去模块寻找指定函数,并执行。利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!

有四个可以实现自省的函数:hasattr,getattr,setattr,delattr

user = User()
while True:choose = input('>>>').strip()if hasattr(user,choose):func = getattr(user,choose)func()else:print('输入错误。。。。')

内置方法

__class____delattr__
__dict__
__dir__
__doc__
__eq__
__format__
__ge__
__getattribute__
__gt__
__hash__
__init__
__init_subclass__
__le__
__lt__
__module__
__ne__
__new__
__reduce__
__reduce_ex__
__repr__
__setattr__
__sizeof__
__str__
__subclasshook__
__weakref__

异常机制

异常(Exception)是一个事件,该事件可能会在程序执行过程中发生,影响了程序的正常执行
raise语句显式的抛出异常
Python解释器自己检测到异常并引发它

异常的固定结构:

try:被检测的代码块
except 异常类型:try中一旦检测到异常,就执行这个位置的逻辑

自定义异常:
python中提供的错误类型可能并不能解决所有错误

如果以后你在工作中,出现了某种异常无法用已知的错误类型捕获(万能异常只能捕获python中存在的异常),那么你就可以尝试自定义异常,只要继承BaseException类即可

自定义异常:
class HelloError(Exception):def __init__(self,n):self.n=n
try:n=input("请输入数字:")if not n.isdigit():raise HelloError(n)
except HelloError as hi:print("HelloError:请输入字符。\n您输入的是:",hi.n)
else:print("未发生异常")

python类和对象最全详解(持续修订中)相关推荐

  1. 【JavaSE】Java类和对象(重点详解)_Java SE

    ✨作者:@小孙的代码分享 ✨专栏:<Java SE> ✨送给各位的一句话:空杯心态 才能学到新知 ✨希望大家看完博客可以有所收获,别忘了,点赞+评论! 1.面向对象 我们开始学习编程遇到了 ...

  2. Python类与对象最全总结大全(类、实例、属性方法、继承、派生、多态、内建函数)

    目录 面向对象编程 常用术语/名词解释 抽象/实现 封装/接口 合成 派生/继承/继承结构 泛化/特化 多态 自省/反射 访问限制 私有属性和公有属性 私有方法的设置 类 创建类 声明与定义 类属性 ...

  3. python类装饰器详解-Python类装饰器实现方法详解

    本文实例讲述了Python类装饰器.分享给大家供大家参考,具体如下: 编写类装饰器 类装饰器类似于函数装饰器的概念,但它应用于类,它们可以用于管理类自身,或者用来拦截实例创建调用以管理实例. 单体类 ...

  4. Python中类、对象与self详解

    先介绍一下python中的类与对象/实例.然后详细说明self.说明:对象等同实例,本文称呼不一致时请自行统一 [一]类与对象/实例 1.类 (1)类由名称.属性.方法三部分组成 (2)类是抽象模板, ...

  5. 类与对象的创建详解(适合新人)

    概念在上一篇文章讲了,那么接下来用代码写类 类: class关键字 [public]:访问修饰符,[]表示括号里的内容可以省略,但是做跨项目去访问的时候不可以省略 类里的成员:字段,属性,方法 语法: ...

  6. python 多继承与super使用详解_继承中的MRO与super详解

    Python进阶-继承中的MRO与super 写在前面如非特别说明,下文均基于Python3 摘要 本文讲述Python继承关系中如何通过super()调用"父类"方法,super ...

  7. ElasticSearch搜索引擎详解-持续更新中

    ElasticSearch搜索引擎详解 1. ElasticSearch概述 1.1 elasticsearch是什么 1.2 全文搜索引擎 1.3 elasticsearch and solr 1. ...

  8. 类和对象常见题目详解

    文章目录 前言 1. 求1+2+3+...+n

  9. php怎么配置configure,PHP编译参数configure配置详解(持续更新中)

    编译参数-使用 ./configure -h 在源代码目录中,该命令可以查看所有编译参数以及对应的英文解释 编译参数-说明 --prefix=/opt/php //指定 php 安装目录 --with ...

  10. VIM查找和替换字符串命令详解(持续更新中...)

    vi/vim 中可以使用 :s 命令来替换字符串.该命令有很多种不同细节使用方法,可以实现复杂的功能,记录几种在此,方便以后查询.    :s/vivian/sky/ 替换当前行第一个 vivian ...

最新文章

  1. 从概念到应用,终于有人把数据挖掘讲明白了
  2. 高并发系统三大利器之限流
  3. 百度 php 图片文字识别,PHP实现百度OCR文字识别
  4. SQL server的with的用法(一)
  5. 【Paper】2020_异构无人机编队防御及评估策略研究_左剑凯
  6. Linux 服务器带宽异常跑满分析解决
  7. Unit05: window 常用子对象-2 、 event 对象 、 Cookie
  8. 为什么要使用Entity Framework
  9. sql修改链接服务器名称,SQL Server 创建链接服务器的脚本,自定义链路服务器的简短名称...
  10. appsan可以扫描linux吗,[经验]使用appscan实现多站扫描简单自动化
  11. 【SLAM笔记】SLAM概述
  12. 赛尔笔记 | 对比学习简述
  13. mysql入门很简单习题答案_《MySQL入门很简单》练习6.6
  14. LaTeX tabular表格环境与命令
  15. Java动态数组ArrayList
  16. HIVE一些字符处理
  17. 数学基础二:点到直线距离公式推导
  18. 同一目录下批处理执行Word宏
  19. 天冕数据开发平台通过信通院“大数据产品能力评测”
  20. upc 去除干员 (delete)

热门文章

  1. 什么是旅行商问题(Traveling Salesman Problem, TSP)?
  2. 字节跳动后端开发实习生面试经验
  3. 苹果无线耳机连接不上_为什么我们一定要买TWS真无线耳机?
  4. 马化腾和朱啸虎互怼之后,摩拜ofo合并可能性基本为零
  5. 《FreeKick》战术_游戏前线
  6. 小程序错误:Setting data field collected to undefined is invalid.
  7. Java流程控制:用for循环打印一个三角形
  8. 域名网址被微信屏蔽的解决方案微信域名网址被屏蔽了红了如何继续使用
  9. ENVI处理高分一号PMS影像数据
  10. 程序员实习期馒头加酸菜,转正后月薪10K起步:走路都带风!