
Python面向对象(继承、多态、封装、传参方式、鸭子类型、局部变量)
发布日期:2021-05-14 22:00:51
浏览次数:21
分类:精选文章
本文共 6613 字,大约阅读时间需要 22 分钟。
Python面向对象:
1.类的属性可以通过实例化对象动态添加
2.传参方式:
1)所谓模子就是类抽象的2)对象 = 类名()
3)过程:
(1)类名():首先会创造出一个对象,创建了一个self变量 (2)调用init方法,类名括号里的参数会被这里接收 (3)执行init方法 (4)返回self对象,self就是一个特殊的大字典# __init__,调用,执行class A: count = 0 def __init__(self): A.count += 1f1 = A()f2 = A()print(f1.count) # 2print(f2.count) # 2
class A: def __init__(self, a): self.a = a def func(self): print(self.a) print(self.b) print(self.c)a = A(2)a.b = 44 # 可以给实例化对象动态添加类的属性a.c = 55a.func() # 2 44 55print(a.__dict__) # {'a': 2, 'b': 44, 'c': 55} 查看实例化对象的所有属性print(A.__dict__) # {'__module__': '__main__', '__init__' ... ...} 查看类的所有方法
3.类中的局部变量,可变数据类型修改是共享的,不可变数据类型修改仅限于实例化对象
class A: name = ['wang'] # 可变数据类型 age = 22 # 不可变数据类型 def __init__(self, *args): # args : () self.a = args[0] def func(self): # 类的局部变量,函数内可以这样调用 print(A.name, A.age) # ['wang'] 22 print(self.a) print(self.b) print(self.c)print('-----', A.name) # ----- ['wang']a = A(2)a.b = 44 # 可以给实例化对象动态添加类的属性a.c = 55a.func() # 2 44 55a.name[0] = 'liu' # 修改类中的变量a.age = 18# 可变数据类型修改是共享的(类和实例化对象共享),不可变数据类型修改不共享,只在自己的实例化对象有效print(a.name, a.age) # ['liu'] 18print(A.name, A.age) # ['liu'] 22print(a.__dict__) # {'a': 2, 'b': 44, 'c': 55, 'age': 18} 查看实例化对象的所有属性# 查看类的所有方法和属性print(A.__dict__) # {'__module__': '__main__', 'name': ['liu'], 'age': 22, '__init__' ...}
类中的局部变量可以通过类名来访问
class A: name = ['wang'] # 可变数据类型 age = 22 # 不可变数据类型 def __init__(self, *args): # args : () self.a = args[0] def func(self): # 类的局部变量,函数内可以这样调用 print(A.name, A.age) # ['wang'] 22 print(self.a) print(self.b) print(self.c)print('-----', A.name) # ----- ['wang']
4.一个类的定义不一定要__init__
5.面向对象的三大特性:继承,多态,封装
6.组合:一个对象的属性值是另外一个类的对象,类的实例化对象可以做类的属性
7.类的继承:
# 一个类可以被多个子类继承# 一个类也可以继承多个父类class A:pass #父类,基类,超类class B:pass #父类,基类,超类class A_son(A,B):pass#子类,派生类print(A_son.__bases__) # (, )print(A.__bases__) # ( ,) 默认继承隐藏超类object
多继承:一个类继承多个父类 路径:A -> B -> C
# 多继承class A: def func(self):print('A')class B: def func(self):print('B')class C: def func(self): print('C')class D(A,B,C): passd = D()d.func() #离的最近的func方法,应该是A的
钻石继承:被继承的两个类继承同一个类
# 钻石继承 : 被继承的两个类继承同一个类class A: def func(self):print('A')class B(A): def func(self):print('B')class C(A): def func(self): print('C')class D(B,C): pass# 继承路径 D -> B -> C -> Ad = D()d.func() #离的最近的func方法,因该是B的,若B中没有func该找C的若B,C中都没有,该找A的
漏斗继承:被继承的两个类分别继承不同的类
class A: def func(self):print('A')class E: def func(self):print('E')class B(A): def func(self):print('B')class C(E): def func(self): print('C')class D(B,C): passprint(D.mro()) #可记录继承路径 D -> B -> A -> C -> Ed = D()d.func() #离的最近的func方法,应该是B的,若B中没有func,该找A的,若A中也都没有该找C的
(1)经典类深度优先 python2.7新式经典共存,新式类要继承object
(2)新式类广度优先 python3.7只有新式类,默认继承object, mro, super方法只有新式类中有,super只在python3.7中有 (3)super的本质:不是直接找父类,而是根据调用者的节点位置的广度优先顺序来的菱形继承:

# 菱形继承:继承的两个类分别继承不同的类,不同的类又继承同一个类# 类的先后顺序不可以交换class F: def func(self): print('F')class A(F): def func(self):print('A')class B(A): def func(self):print('B')class E(F): def func(self): print('E')class C(E): def func(self):print('C')class D(B,C): passprint(D.mro()) #可记录继承路径 D -> B -> A -> C -> E -> Fd = D()d.func() #离的最近的func方法,应该是B的,若B中没有func,找A的,A没找C,C没找E,都没找F
接口类和抽象类:
1、抽象类规范
一般情况下单继承能实现的功能都是一样的,所以在父类中可以有一些简单的基础实现 多继承的情况,由于功能比较复杂,所以不容易抽象出相同的功能的具体实现写在父类中2、抽象类还是接口类:面向对象的开发规范
(1)python中没有接口类:java里有接口Interface这个概念 (2)python中自带多继承,所以我们直接用class来实现了接口类 (3)python中支持抽象类:一般情况下单继承不能实例化 (4)多态python天生支持多态(动态强类型的语言)3、鸭子类型
(1)不崇尚根据继承所得来的相似 (2)我只是自己实现自己的代码就可以了 (3)如果两个类刚好相似,并不产生父类的子类的兄弟关系,而是鸭子类型 例:tuple list 这种相似是自己写代码时约束的,而不是通过父类约束的 (4)优点:松耦合 每个相似的类之间都没有影响接口类:
python不支持,默认是多继承,所有方法都必须不能实现# 接口类from abc import abstractmethod,ABCMetaclass Payment(metaclass=ABCMeta): # 元类 默认的元类 type @abstractmethod def pay(self): raise NotImplemented # 没有实现这个方法class Wechat: def pay(self, money): print('微信支付了%s元'%money)class Alipay: def pay(self, money): print('支付宝支付了%s元'%money)class Applepay: def fuqian(self, money): # 这个类没有pay这个方法 print('Applepay支付了%s元'%money)def pay_for(pay_obj, money): # 统一支付入口 pay_obj.pay(money)wechat = Wechat()ali = Alipay()apple_pay = Applepay()pay_for(wechat, 200) # 微信支付了200元pay_for(ali, 300) # 支付宝支付了300元# pay_for(apple_pay, 100) # 报错 'Applepay' object has no attribute 'pay'
抽象类:
python支持,不支持多继承from abc import abstractmethod,ABCMetaclass Swim_Animal(metaclass=ABCMeta): @abstractmethod def swim(self): passswim_animal = Swim_Animal()class Walk_Animal(metaclass=ABCMeta): @abstractmethod def walk(self): passwalk_wnimal = Walk_Animal()class Fly_Animal(metaclass=ABCMeta): @abstractmethod def fly(self): passfly_animal = Fly_Animal()class Tiger(Walk_Animal,Swim_Animal): def walk(self): pass def swim(self): passclass Swan(Walk_Animal,Fly_Animal,Swim_Animal):passtiger = Tiger()tiger.walk()
静态方法:
在完全面向对象的程序中,如果一个函数既和对象没有关系也和类没有关系那么就用staticmethod将这个函数变成一个静态方法class Login: def __init__(self,name,password): self.name = name self.pwd = password def login(self): pass @staticmethod def get_usr_pwd(): #没有默认参数,就像函数一样 usr = input('用户名:') pwd = input('密码:') Login(usr,pwd)Login.get_usr_pwd()
封装:
1、广义上面向对象的封装:代码的保护,面向对象的思想本身就是一种封装 2、只让自己的对象能调用自己类的方法 3、狭义上的封装 – 面向对象三大特性 4、属性和方法都藏起来,不让你看见Testcase:
1.下面代码输出结果为: # 20, 10, Nonea = 10b = 20def func(a, b): print(a, b)c = func(b, a)print(c) # 20, 10, None 无返回值return
2.求字符串中数字的和:
# 正则匹配求和 + 1-n次 ? 0-1次 * 0-n次# 方法一import res='123.33sdhf3424.34fdg323.324asda123'p = r'\d+\.?\d*'r = re.findall(p, s) # ['123.33', '3424.34', '323.324', '123']print(sum([float(i) for i in r])) # 3993.994# 方法二import res='123.33sdhf3424.34fdg323.324asda123'p = r'\d+\.?\d*'r = re.findall(p, s)r = '+'.join(r)print(r) # '123.33+3424.34+323.324+123'print(eval(r)) # 3993.994 eval()函数求值
3.输出值为list类型的key组成一个list:
# 输出字典中值为list的keyd={'k1':'v1','k2':[1,2,3],('k','3'):{1,2,3}}ret = [k for k in d if type(d[k]) is list]print(ret)
4.匹配方式
# strings字符串的筛选# http开头的https开头的# IP地址import re# if self.strings[k][1]# 要不要匹配HTTP和HTTPS的,是开头match匹配还是全部search匹配s = 'http://www.baidu.com's1 = 'https://www.163.com's3 = '/.,[,;],;ahm,ldshs'# 从头开始匹配,开头为https和httpif re.match(r"http|https", s3): print(re.match(r"http|https", s3))else: print('can not match')# 匹配到是把IP提取出来,还是把原字符串存储下来s2 = 'fsdf172.123.7.2sdfsg'if re.findall(r'\d+\.\d+\.\d+\.\d+', s3): print(re.findall(r'\d+\.\d+\.\d+\.\d+', s3)) print(re.findall(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', s3)) # 返回一个listelse: print('22222')
发表评论
最新留言
关注你微信了!
[***.104.42.241]2025年04月29日 21时46分45秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
block多队列分析 - 2. block多队列的初始化
2021-05-12
Java时间
2021-05-12
不编译只打包system或者vendor image命令
2021-05-12
The wxWindows Library Licence (WXwindows)
2021-05-12
leetcode——第203题——虚拟头结点
2021-05-12
【编程】C语言入门:1到 100 的所有整数中出现多少个数字9
2021-05-12
MySQL----基础及常用命令
2021-05-12
flink启动(二)
2021-05-12
前端开发进阶手册.pdf
2021-05-12
软件架构设计和MESH经验之谈
2021-05-12
关于宝塔面板安装的mysql用Navicat连接出现2003的错误解决
2021-05-12
Windows2016 FTP用户隔离
2021-05-12
js传入参数是中文的时候出现 “******”未定义错误
2021-05-12
吴恩达机器学习课程笔记(英文授课) Lv.1 新手村(回归)
2021-05-12
pair的用法
2021-05-12
SQL基本操作命令
2021-05-12
C# WinForm程序退出的方法
2021-05-12
onFailure unexpected end of stream
2021-05-12
Flex 布局的自适应子项内容过长导致其被撑大问题
2021-05-12
PL/SQL 动态Sql拼接where条件
2021-05-12