zoukankan      html  css  js  c++  java
  • 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__}	_instance	{self._instance}')
            print(f'{self.__class__.__name__}	__instance	{self.__instance}')
            print(f'{self.__class__.__name__}	__instance__	{self.__instance__}')
    
        def get_b(self):
            print(f'{self.__class__.__name__}	_instance	{self._instance}')
            print(f'{self.__class__.__name__}	__instance	{self.__instance}')
            print(f'{self.__class__.__name__}	__instance__	{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仓库地址
  • 相关阅读:
    Raw图像格式
    Basler相机外部触发设置(Halcon)
    C# 丢弃串口缓冲区 Serialport.DiscardInBuffer,DiscardOutBuffer
    ASCII 码
    Xcopy 使用详解
    Qt 信息提示框QMessageBox用法
    Qt 调整图片大小适应QLabel
    C++取整
    Qt QTableView数据列宽度自适应, 横向填满表格
    Qt 事件总结(鼠标、键盘) QMouseEvent、QKeyEvent
  • 原文地址:https://www.cnblogs.com/satansz/p/12906508.html
Copyright © 2011-2022 走看看