python系列整理---面向对象
一.基本概念
1. 类是抽象的,具有相同属性和方法(行为)的集合
2. 对象是具体的,具有某些属性和方法(行为)的
3. 创建的对象的过程,叫实例化
4. 属性与方法
1) 实例属性:self动态方式调用、赋值,及self.leg='new leg'仅限于当前对象
2) 实例方法: 同上
3) 静态属性: 以self动态方式调用、赋值时,仅限于当前对象;直接对静态属性Animal.leg='leg'调用时,贯穿所有对象
4) 静态方法: 同上
5) 类属性
6) 类方法
二.继承
1.继承了父类的基本属性和方法
2.可以继续实现自己的属性和方法
3.方法重写:同名函数重写,用另一种实现方案实现父类的方法
class SetOperation: all_dict = {} def __init__(self, s1, s2): self.s1 = s1 self.s2 = s2 self._dict = {} self.set() # __var private 私有变量, 仅当前类内部使用, 外部不可直接访问,子类也不能继承 # __method__ protect 魔法方法, 它只允许在该类的内部中使用, 意味着这个方法子类不能被重写 (继承) ## _var, __var__ 变量的访问权限没有限制 ## _method, protect私有方法, 仅当前类内部使用 self._instance = '_aaa' self.__instance = '__aaa' self.__instance__ = '__aaa__' self.s3 = None self.s4 = None def set(self): # 字典计数 for i in self.s1: self._dict[i] = self._dict.get(i, 0) + 1 for j in self.s2: self._dict[j] = self._dict.get(j, 0) + 1 def set3(cls, s1, s2): cls.s1 = s1 cls.s2 = s2 @staticmethod def set2(s1, s2): # 字典计数 for i in s1: SetOperation.all_dict[i] = SetOperation.all_dict.get(i, 0) + 1 for j in s2: SetOperation.all_dict[j] = SetOperation.all_dict.get(j, 0) + 1 def get(self): intersect, union, s12, s21 = set(), set(), set(), set() # 字典分类 for k, v in self._dict.items(): union.add(k) if v > 1: intersect.add(k) else: if k in self.s: s12.add(k) else: s21.add(k) return [intersect, union, s12, s21] def intersect(self): print('self._dict') intersect = set() for k, v in self._dict.items(): if v > 1: intersect.add(k) return intersect def union(self): # return set(self._dict.keys()) union = set() for k, v in self._dict.items(): union.add(k) return union def set_b(self): self._instance = '_bbb' self.__instance = '__bbb' self.__instance__ = '__bbb___' print(f'{self.__class__.__name__}\t_instance\t{self._instance}') print(f'{self.__class__.__name__}\t__instance\t{self.__instance}') print(f'{self.__class__.__name__}\t__instance__\t{self.__instance__}') def get_b(self): print(f'{self.__class__.__name__}\t_instance\t{self._instance}') print(f'{self.__class__.__name__}\t__instance\t{self.__instance}') print(f'{self.__class__.__name__}\t__instance__\t{self.__instance__}') def _set_b(self): self.s4 = 'ttttt' def __set_b__(self): self.s3 = 'sssss' def __setitem__(self, key, value): """ 属性变量赋值时会调用__setitem__, 区别在于如果将对象当作字典操作,设置键值对时会触发该方法, 同样在__setitem__(self, key, value)方法内对属性进行赋值时, 也不能使用self.name = value,而应该使用self.__dict__['name'] = value. """ print(f'__setitem__: {key}--->{value}') self.__dict__[key] = value def __getitem__(self, item): return self.__dict__.get(item) def __setattr__(self, key, value): """ 属性变量赋值时会调用__setattr__, 应该通过对属性字典做索引运算来赋值任何实例属性,也就是使用self.__dict__['name'] = value """ print(f'__setattr__: {key}--->{value}') self.__dict__[key] = value def __getattr__(self, item): return self.__dict__.get(item) # 4个方法 class SetOperation2(SetOperation): """ 继承了父类的基本属性和方法 可以继续实现自己的属性和方法 方法重写:同名函数重写,用另一种实现方案实现父类的方法 """ def __init__(self, s1, s2): SetOperation.__init__(self, s1, s2) self.child = {} print('self.__instance:', self.__instance) self._instance = '_child' self.__instance = '__child' self.__instance__ = '__child__' # super().__init__(s1, s2) # self.s1 = s1 # self.s2 = s2 def intersect(self): print('self.s1 | self.s2') return self.s1 | self.s2 def union(self): return self.s1 & self.s2 def s12(self): return self.s1 - self.s2 def s21(self): return self.s2 - self.s1 def __set_b__(self): self.s3 = '33333'
三.设计模式
1. 装饰器
# coding=utf-8 import time from functools import wraps import traceback def stat_time(func): """统计函数或方法运行的时间""" @wraps(func) def opt(*arg, **kwargs): start_time = time.time() func(*arg, **kwargs) end_time = time.time() cha_time = end_time - start_time print(f'{func.__name__} method spend time {round(cha_time, 3)}') return opt def retry(max_times=3): def retry_func(func): @wraps(func) def wrapper(*arg, **kwargs): res = None for i in range(max_times): try: res = func(*arg, **kwargs) break except: print(traceback.print_exc()) return res return wrapper return retry_func if __name__ == '__main__': @retry(3) def abc(): return 3 / 0 abc()
2. 单实例
# coding=utf-8 from functools import wraps class Singleton: instance_pool = {} instance_pool_list = [] class SingletonType(type): """ 最优先使用的方式, 此种方法定义的单实例可以被继承 1.类由type创建,创建类时,type的__init__方法自动执行,类() 执行type的 __call__方法(类的__new__方法,类的__init__方法) 2.对象由类创建,创建对象时,类的__init__方法自动执行,对象()执行类的 __call__ 方法 """ def __call__(cls, *args, **kwargs): cls_key = (cls.__name__, args, tuple(kwargs.items())) cls_instance = Singleton.instance_pool.get(cls_key, None) if not cls_instance: cls_instance = super(SingletonType, cls).__call__(*args, **kwargs) Singleton.instance_pool[cls_key] = cls_instance return cls_instance class SingletonListType(type): """ 和SingletonType一样, 此种方法定义的单实例的类【可以被继承】 1.类由type创建,创建类时,type的__init__方法自动执行,类() 执行type的 __call__方法(类的__new__方法,类的__init__方法) 2.对象由类创建,创建对象时,类的__init__方法自动执行,对象()执行类的 __call__ 方法 """ def __call__(cls, *args, **kwargs): for _cls_name, _args, _kwargs, _instance in Singleton.instance_pool_list: if (_cls_name, _args, _kwargs) == (cls.__name__, args, kwargs): return _instance else: _instance = super(SingletonListType, cls).__call__(*args, **kwargs) Singleton.instance_pool_list.append((cls.__name__, args, kwargs, _instance)) return _instance class SingletonDecClass: """ 使用装饰器方法,但此种方法定义的单实例的类【不可以被继承】 1.类由type创建,创建类时,type的__init__方法自动执行,类() 执行type的 __call__方法(类的__new__方法,类的__init__方法) 2.对象由类创建,创建对象时,类的__init__方法自动执行,对象()执行类的 __call__ 方法 """ def __init__(self, cls): self.cls = cls def __call__(self, *args, **kwargs): for _cls_name, _args, _kwargs, _instance in Singleton.instance_pool_list: if (_cls_name, _args, _kwargs) == (self.cls.__name__, args, kwargs): return _instance else: _instance = self.cls(*args, **kwargs) Singleton.instance_pool_list.append((self.cls.__name__, args, kwargs, _instance)) return _instance class SingletonDecMethod(object): """ 使用装饰器方法,但此种方法定义的单实例的类【不可以被继承】 """ @staticmethod def singleton(cls): # 定义一个私有方法,wraps作用不知道的自己查,不感兴趣的也不用知道 @wraps(cls) def __wrapper(*args, **kwargs): cls_key = (cls.__name__, args, kwargs) cls_instance = Singleton.instance_pool.get(cls_key) if not cls_instance: cls_instance = cls(*args, **kwargs) cls._instance_pool[cls_key] = cls_instance return cls_instance return __wrapper class SingletonExample(object): """ 使用 __new__ 定义单实例 正常定义类的模式, 需要重写 __new__方法 """ _instance = None def __init__(self, *args, **kwargs): pass def function(self, *args, **kwargs): pass def __new__(cls, *args, **kwargs): if not SingletonExample._instance: SingletonExample._instance = object.__new__(cls, *args, **kwargs) return SingletonExample._instance
3. 工厂模式
组成:
1. 工厂基类,用来复制-扩展规模,提供一个抽象化的接口来创建一个特定类型的对象
2. 工厂函数类,通过继承工厂基类引申出来的类组成工厂类列表,并通过条件判断返回符合条件的具体对象
例子:
1)BaseSite是基类,Tencent、Iqiyi都是继承BaseSite的类,并分别添加至工厂类
2)SiteFactory是工厂函数类,get_site是类工厂函数,提供对工厂列表中具体类的访问方式
# coding=utf-8 class BaseSite: url_patterns = [] def process(self): print('process common') class Tencent(BaseSite): url_patterns = ['https://www.qq.com'] def __init__(self): BaseSite.__init__(self) def process(self): print('process Tencent') class Iqiyi(BaseSite): url_patterns = ['https://www.iqiyi.com'] def __init__(self): BaseSite.__init__(self) def process(self): print('process iqiyi') class SiteFactory: def __init__(self): self.all_sites = [] self.init_factory() def add_site(self, cls): self.all_sites.append(cls) def init_factory(self): self.add_site(Tencent()) self.add_site(Iqiyi()) def get_site(self, url): import re for site in self.all_sites: for pattern in site.url_patterns: if re.search(pattern, url): return site if __name__ == '__main__': site_factory = SiteFactory() url = 'https://www.iqiyi.com/19191' site = site_factory.get_site(url) site.process()
https://github.com/jiangsiwei2018/BigData.git
实例代码git仓库地址