2-面向对象
0x-wen

3.面向对象

3.1 三大特性

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 面向对象三大特性:继承 封装 多态
class Base(object):
def __init__(self):
self.leg = "4"

def func1(self):
print(f"Base 有 {self.leg} 条腿...")


class Cat(Base):
def func1(self):
print(f"我是cat,有{self.leg}条腿...")
print("我会上树")


class Dog(Base):
def func1(self):
print(f"我是dog,有{self.leg}条腿...")
print("我跑得快")


class Table(Base):
def func1(self):
print(f"我是一个餐桌,也有{self.leg}条腿,但我不会跑...")


def func(arg):
arg.func1()


func(Base())
func(Dog())
func(Cat())
func(Table())

3.2 类方法和静态方法

classmethod 给类定义的方法
staticmethod 目的只是封装在一起,内聚

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Person(object):

def __init__(self, name):
self.name = name

@classmethod
def name(cls, name):
return cls(name)

@staticmethod
def age(age: int):
return age

def __repr__(self):
return self.name


a = Person(name="张三")
print(a)
b = Person.name("李四")
print(b)
print(a.age(18)) # 对象可以调用
print(Person.age(20)) # 类也可以调用

3.3 property装饰器

1.将函数属性伪装成数据属性
2.统一数据属性的查、改、删操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Person:
def __init__(self, name):
self.__name = name

@property
def name(self):
return self.__name

# 当name 遇到赋值操作, 即 = 时触发被property.setter装饰的函数的执行
@name.setter
def name(self, value):
self.__name = value

# 当name 遇到删除操作,即 del 时触发property.deleter装饰的函数的执行
@name.deleter
def name(self):
print('deleter')


obj1 = Person('abc')
print(obj1.name)
obj1.name = 'aaa'
print(obj1.name)
del obj1.name

3.4 cached_property

相比 property 增加缓存功能,针对不可变的高计算资源消耗的实例特征属性

1
2
from functools import cached_property  # 内置 3.8版本才加入的cached_property
pip3 install cached-property # 第三方包 支持asyncio

3.5 属性查找顺序

对象 —> 父类 —> 继承类, 依次类推,找不到则报错

3.6 多继承

  • 多继承的优点:同时继承多个父类属性和方法,功能强大。
  • 多继承缺点:代码可读性变差。
  • 通过类的mro()方法查看多继承的查找顺序。
  • __bases__ 可以查看类继承的所有父类
1
2
3
print(C.mro())
# [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
print(C.__bases__) # (<class '__main__.A'>, <class '__main__.B'>)

3.7 广度优先和深度优先

1
2
3
4
5
6
7
# [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.A1'>, <class '__main__.B'>, <class 'object'>]

# python3中全部默认继承object,所以都是新式类
- object类提供了一些常用内置方法的实现,如用来在打印对象时返回字符串的内置方法__str__

新式类:广度优先
obj -> <class '__main__.C'> -> <class '__main__.A1'> ... -> <class 'object'>

3.8 抽象基类

1.抽象类本身不能实例化

2.子类必须实现其定义接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import abc


# 指定metaclass属性将类设置为抽象类,抽象类本身不能实例化
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod # 该装饰器限制子类必须定义有一个名为talk的方法
def talk(self): # 抽象方法中无需实现具体的功能
pass


class Cat(Animal): # 但凡继承Animal的子类都必须遵循Animal规定的标准
def talk(self): # 必须定义talk方法
pass


cat = Cat() # 若子类中没有一个定义talk的方法则会抛出异常TypeError,无法实例化

3.9 isinstance 和 issubclass

1
2
print(isinstance(a, int))  # 断言类型
print(issubclass(People, Animal)) # 断言是否其子类

3.10 动态获取对象信息(反射)

1
2
3
4
hasattr(obj, 'x')	                    # 判断对象是否有一个属性,返回布尔值
getattr(object, name, default=None) # 获取对象的name属性,name属性不存在的返回None
setattr(x, 'y', 'v') # 更新x对象 y属性的值, 等价于 x.y = 'v',当y不存在的新增
delattr(x, 'y') # 删除x对象 y属性, 等价于 del x.y 属性y不存在则报错
由 Hexo 驱动 & 主题 Keep
总字数 42.8k