面向对象基础
面向对象编程
面向过程编程:类似于工厂的流水线。
优点:逻辑清晰;
缺点:扩展性差。
面向对象编程:核心是对象二字,对象是属性和方法的集合体,面向对象编程就是一堆对象交互。
优点:扩展性强;
缺点:逻辑非常乱。
类与对象
对象:属性和方法的集合体。
类:一系列相同属性和方法的集合体。
现实世界中先有对象后有类;
Python中先有类,再实例化对象。
对象的属性的查找顺序
先对象本身 --> 类 --> 父类 --> 父类的父类 --> object --> 自己定制的元类 --> type
给对象定义私有属性
python
class People:
pass
p1 = People()
p1.name = 'jack'
p2 = People()
p2.name = 'tank'
对象的绑定方法
python
class People:
def eat(self):
print(self,'eat...')
p1 = People()
p1.eat()
p1.name = 'jack'
p2 = People()
p2.eat()
p2.name = 'tank'
类与数据类型
python
# lis = list([1, 2, 3])
lis = [1, 2, 3]
# 对象调用对象绑定的方法,会自动传参
lis.append(4)
# 类调用对象绑定的方法,必须得传参
list.append(lis, 4)
面向对象进阶
类的继承
继承父类,则会有父类的所有属性和方法。
类的派生
继承父类的同时,自己有init,然后也需要父类的init。
类的组合
把类对象可以引用/当做参数传入/当作返回值/当做容器元素,类似于函数对象。
菱形继承问题
新式类:继承object的类,python3中全是新式类。
经典类:没有继承object的类,只有python2中有。
在菱形继承的时候,新式类是广度优先(老祖宗最后找);经典类是深度优先(一路找到底,再找旁边的)。
多态与多态性
一种事物的多种形态。
类的封装
隐藏属性,只有类内部可以访问,类外部不可以访问。
类的property特性
把方法变成属性引用。
类与对象的绑定方法和非绑定方法
没有任何装饰器装饰的方法就是对象的绑定方法,类能调用,但是必须传参给self。
被@classmethod装饰器装饰的方法就是类方法,参数写成cls,cls是类本身,对象也能调用,参数cls还是类本身。
被@staticmethod装饰器装饰的方法就是非绑定方法,就是一个普通的函数。
面向对象高级
isinstance,issubclass
(魔术方法)
isinstance:判断是否为类的实例化对象,会检测父类,而type不会检测父类。(取代type)
type:获取实例化对象的类,不会检测父类。type是用来生成类的。
issubclass判断是否为其子类。
反射
- hasattr:通过字符串判断是否类属性存在;
- getattr:通过字符串获取类属性;
- setattr:通过字符串修改类属性;
- delattr:通过字符串删除类属性。
call
对象加()调用的时候触发。
python
class Foo:
def __init__(self):
print('Foo()会触发')
def __call__(self):
print('f()会触发')
f = Foo()
f()
new
python
class Foo:
def __new__(self):
print('new')
obj = object.__new__(self)
return obj
def __init__(self):
print('init')
f = Foo()
元类
元类用来造类的。
元类() --> 类 --> init
元类() () --> 对象 --> call
类分为几部分:类名/类体名称空间/父类们。
python
class Mymeta(type):
def __init__(self, class_name, class_bases, class_dic):
# 控制类的逻辑代码
super().__init__(class_name, class_bases, class_dic)
def __call__(self, *args, **kwargs):
# 控制类实例化的参数
obj = self.__new__(self) # obj就是实例化的对象
self.__init__(obj, *args, **kwargs)
# 控制类实例化的逻辑
return obj
class People(metaclass=Mymeta):
def __init__(self, name, age):
self.name = name
self.age = age
单例模型
利用类的绑定方法的特性
python
NAME = 'nick'
AGE = 18
class People():
__instance = None
@classmethod
def from_conf(cls):
if cls.__instance:
return cls.__instance
cls.__instance = cls(NAME, AGE)
return cls.__instance
People.from_conf()
利用装饰器
python
NAME = 'nick'
AGE = 18
def deco(cls):
cls.__instance = cls(NAME, AGE)
def wrapper(*args, **kwargs):
if len(args) == 0 and len(kwargs) == 0
res = cls(*args, **kwargs)
return res
return wrapper
@deco
class People():
def __init__(self, name, age):
self.name = name
self.age = age
peo1 = People()
peo2 = People()
利用元类(正宗的)
python
NAME = 'nick'
AGE = 18
class Mymeta(type):
def __init__(self, class_name, class_bases, class_dic):
super().__init__(class_name, class_bases, class_dic)
self.__instance = self(NAME, AGE)
def __call__(self, *args, **kwargs):
if len(args) == 0 and len(kwargs) == 0
return self.__instance
obj = self.__new__(self)
self.__init__(obj, *args, **kwargs)
return obj
class People(metaclass=Mymeta):
def __init__(self, name, age):
self.name = name
self.age = age
peo1 = People()
peo2 = People()