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, None

a = 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')
上一篇:Python网络编程(Socket套接字、TCP粘包问题)
下一篇:Python基础(可变数据类型不能做函数参数、装饰器、剥皮函数、时间间隔)

发表评论

最新留言

关注你微信了!
[***.104.42.241]2025年04月29日 21时46分45秒