zoukankan      html  css  js  c++  java
  • 多态

    多态的概念:
    一种事务具备不同的形态
    例如:
    比如人有多重形态:
    黑人 白人 黄种人 老人 小孩
    程序中的多态是指,不同对象可以相应方法,并可以有自己不同的实现方式

    多态不是一种特殊的语法,它是一种状态,是一种个特性(多个不同的对象使用一种相同的方法,产生不不同的结果
    也就是不同的对象使用相同的方法.
    多态案例
    import abc
    
    class Animal(metaclass=abc.ABCMeta):  #  同一种类事务: 动物
        @abc.abstractmethod
        def talk(self):
            pass
    
    class People(Animal):  # 动物的形态之一: 人
        def talk(self):
            print('你好!')
    
    class Dog(Animal):
        def talk(self):
            print('汪汪汪')
    
    a = People()
    B = Dog()
    a.talk()
    B.talk()
    
    class Cat(Animal):
        def talk(self):
            print('喵喵')
    
    c = Cat()
    c.talk()
    多态的来的好处:
    1.增加程序的灵活性
    以不变应万变,不论对象的千变万化,使用者都是以同一个形式去调用
    2.增加了程序的可扩展性,降低了使用的难度
    鸭子类型:
    python中崇尚鸭子类型,看起来像鸭子,叫声像鸭子那么它就是鸭子
    python程序员通常根据这种标准来编写程序.如果想编写现有对象的自定义版本可以继承这个对象
    也可以穿件一个外观和行为像,但是与它没有任何关系的全新对象,后者通常用于保存程序的耦合度.

    isinstance :

    python 中isinstance()函数,是python中的一个内置函数,是用来判断一个函数是否是另一个已知的类型,(和type类似)
    判断一个对象是否是某个类的实例(对象)
    isinstance(object,classinfo)


    参数1 要判断的对象
    参数2 要判断的类型
    返回值: 如果对象的类型与参数二类型相同返回True 反之返回False

    a = 2
    res = isinstance(a,int)
    print(res) #  结果为>>>True
    res = isinstance(a,str)
    print(res)  #  结果为>>>False
    res = isinstance(a,(int,str,list))
    print(res)  #  结果为True 元祖中的一是正确的的所以返回值为True
    

      

    isinstance()和type()的区别
    isinstance()会认为子类父类类型,考虑继承关系
    type()中不会认为子类是一种父类形态,不考虑继承关系.
    class A:
        pass
    
    class B(A):
        pass
    
    res = isinstance(A(),A)
    print(res)    #  True
    print(type(A()))  # <class '__main__.A'>
    print(isinstance(B(),A))   #  True
    print(type(B()))    #  <class '__main__.B'>
    

      

    issubclass:

    判断一个类是否是另一类的子类
    issubclass(class,classinfo)
    参数:
    class--->类
    classinfo---> 父类
    返回值:

    如果class是classinfo的子类返回值True 反之为False

    实例:
    class A:
        pass
    
    class B(A):
        pass
    class C:
        pass
    
    print(issubclass(B, A))  # 结果为True
    print(issubclass(C, A))  # 结果为False
    

      __ste__方法:

    __str__的方法和__int__方法类似,都是以一些特殊的方法,所以前后都有双下划线,它用来返回随想的字符串表达方式
    __str__会对像被转换成字符串时,转换的结果就是这个函数的返回值,我们可以利用该函数来自定义,对象的打印格式

    实例:
    class Person:
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __str__(self):
            return '这是一个person对象 name %s age %s'%(self.name,self.age)
    
    p = Person('jason',12)
    print(p)
    

      

    __del__使用方法:

    创建对象后,Python解释器默认调用__init__()方法。当删除一个对象时,Python解释器也
    会默认调用一个方法,这个方法为__del__()方法。在Python中,对于开发者来说很少会直接
    销毁对象(如果需要,应该使用del关键字销毁)。Python的内存管理机制能够很好的胜任这份
    工作。也就是说,不管是手动调用del还是由Python自动回收都会触发__del__方法执行。

    执行时机:手动删除对象时立马执行,或者是程序运行结束时也会自动执行
    使用场景: 当你的对象在使用过程中,打开了不属于解释器的资源:比如文件,网络端口等

    实例:
    class A(object):
        #创建初始化方法
        # 创建对象后直接被调用
        def __init__(self,name):
            print("__init__初始化方法被调用")
            self.name = name
    
        # 方法 当对象被删除的时候会自动调用
        def __del__(self):
            print('__del__方法被调用了!')
            time.sleep(2)
            print('%s对象马上要被杀死了...'%self.name)
    
    dog = A('哈士奇')
    print('___马上杀死哈士奇')
    del dog
    get = A('苍井空')
    print('___马上干掉苍老师')
    del get
    >>>>
    执行结果:
    __init__初始化方法被调用
    ___马上杀死哈士奇
    __del__方法被调用了!
    哈士奇对象马上要被杀死了...
    __init__初始化方法被调用
    ___马上干掉苍老师
    __del__方法被调用了!
    苍井空对象马上要被杀死了...
    
    >>>>
    

      

    call 使用方法:

    关于__call__方法,不得不要先提到一个概念,就是可调用对象(callable)
    我们平时自定义的函数、内置函数和类都属于可调用对象,但凡是可以把
    一对括号()应用到某个对象身上都可称之为可调用对象,判断对象是否为
    可调用对象可以用函数 callable 如果在类中实现了 __call__ 方法,那
    么实例对象也将成为一个可调用对象,
    什么时候调用: 在调用函数对象的时候会自动执行,也就是加括号的时候

    __call__实例:
    
    class A:
        def __call__(self, *args, **kwargs):
            print('call run')
            print(args)
            print(kwargs)
    a = A()
    a(1,a = 199)
    >>>
    call run
    (1,)
    {'a': 199}
    >>>
    

     

    __slots__节省内存:

     

    该属性是一个类属性,用于优化对象内存占用,优化的原理,将原本不固定的属性数量变得固定。
    从而达到减少内存的占用
    首先我需要这世道动态语言和静态语言
    python属于动态语言:可以在运行的时候修改代码
    c就属于静态语言: 在编译时已经确定好了代码,在运行过程中是不被修改的
    为了达到限制的目的,python允许在定义class的时候定义了一个特殊的__slots__变量来限制
    class实例能添加的属性:
    # __slots__实例
    class Person:
        __slots__ = ('name','age')
    p = Person()
    p2 = Person()
    p.name = '隔壁老王'
    p.age = 89
    print(sys.getsizeof(p))
    print(sys.getsizeof(p2))
    print(sys.getsizeof(p.name))
    print(sys.getsizeof(p.age))
    # print(p.__dict__)  # 没有了__dict__ 所以报错了
    

      

     

    getattr获取属性
    setattr设置属性
    delattr删除属性

     

    getattr()函数用于返回一个对象属性值
    getattr(object,name[,default])
    object--->对象
    name--->字符串,对象属性
    default--->默认返回值,如果不提供这个参数,在没有对应属性时,将触发attbuteerro
    getattr 用点访问属性的时候如果属性不存在的情况下执行
    setattr 用点设置属性
    delattr 用del 对象 .属性 删除属性时执行
    这几个函数反映了python解释器是如何实现用点来访问属性
    getattribute这个函数也是用来获取属性的
    在获取属性时如果存在getattribute则先执行该函数,如果没有拿到属性则继续调用
    getattr函数,如果拿到了则直接返回
    实例:
    class A:
       def __setattr__(self, key, value):
            # print(key)
            # print(value)
            print('__setattr__')
            self.__dict__[key] = value
       def __delattr__(self, item):
            print('__delattr__')
            print(item)
            self.__dict__.pop(item)
            pass
       def __getattr__(self, item):
           print('__getattr__')
           return 345
       def __getattribute__(self, item):
            print('__getattribute__')
            return super().__getattribute__(item)
    
    a = A()
    a.name = 'jason'
    # print(a.name)
    # # a.age = 19
    del a.name
    print(a.name)
    

      

    []的实例:
    getitem 当你用括号去获取属性时执行
    setitem 当用括号去设置属性时 执行
    delitem 当你用括号删除属性时执行

     

    实例:
    
    class MyDict(dict):
        pass
        def __getattr__(self, key):
            return self.get(key)
        def __setattr__(self, key, value):
            self[key] = value
        def __delattr__(self, key):
            del self[item]
    
    a= MyDict()
    a['name'] = 'jack'
    print(a['name'])
    print(a.name)
    a.age = 20
    print(a.age)
    

      

    运算符重载
    当我们在使用某个符号时,python解释器都会为这个符号定义一个含义,同时调用
    对应的处理函数,当我们需要自定义对象的比较规则时,就可在子类中覆盖大于等于
    等等一系列的方法。。
    案例:
    原本自定义对象无法直接使用大于小于等于来进行比较,我们
    可以自定义运算符来实现,让自定义对象也支持比较运算符
    
    
    
    class Student(object):
        def __init__(self,name, age, height):
            self.name = name
            self.age = age
            self.height = height
        def __gt__(self, other):  # 大于
            print(self)
            print(other)
            print("__gt__")
            return self.age > other.age
    
        def __lt__(self, other):
            return self.name < other.name
    
        def __eq__(self, other):
            if self.height == other.height and self.name == other.name and self.age == other.age:
                return True
            return False
    
    s1 = Student('肉丝',20, 175)
    s2 = Student('杰克',20, 175)
    print(s1 < s2)
    print(s1 < s2)
    print(s1 == s2)
    

      

    迭代器协议:
    迭代器是指具有__iter__和__next__的对象,我们可以为对象增加两个方法
    让对象编程一个迭代器
    
    
    案例:
    #迭代器案例:
    class MyRange:
        def __init__(self,start, end, step):
            self.start = start
            self.end = end
            self.step = step
        def __iter__(self):
            return self
        def __next__(self):
            a = self.start
            self.start += self.step
            if a < self.end:
                return a
            else:
                raise StopIteration
    
    for i in MyRange(1,100,2):
        print(i)
    

      

    上下文管理
    上下文context
    这个概念术语语言学科,指的是一段话的意义,要参考当前的场景,即上下文
    在python中,上下文可以理解为是一个代码区间,一个范围,比如with open
    打开文件仅仅是在这个上下文中有效
    上下文涉及了两个方法;
    enter:进入 表示进入上下文,或者说进入某个场景
    exit:推出 表示推出上下文,或者说是退出某场景
    enter 函数应该有返回值,返回值是对象自己
    exit函数可以有返回值,是一个bool值,用于表示一场是否被处理,仅在上下文中出现异常时用
    如果为True 意味着,异常已经被处理了
    False 为异常没有被处理
    当执行with 语句时候会优先执行enter
    当代码制行完毕后制行exit,或者是代码遇到异常会立即制行exit,并传出错误信息
    包含错错误类型,错误信息。错误的追踪信息
    # 实例一
    class Poo:
        def __int__(self):
            print('实例化一个 对象')
        def __enter__(self):
            print('进入...')
        def __exit__(self, exc_type, exc_val, exc_tb):
            print('退出...')
            # return True
            # return False
    p = Poo()
    print(p)
    with p:
        raise ImportError
        print('正在制行。。。')
    #"""出现异常时,如果 __exit__ 返回 False(默认不写返回值时,即为False),则会重新抛出异常,让with 之外的语句逻辑来处理异常,这也是通用做法;如果返回 True,则忽略异常,不再对异常进行处理"""
    
    class MyOpen:
        def __init__(self,path):
            self.path = path
        def __enter__(self):
            self.file = open(self.path)
            print("进入...")
            return self
        def __exit__(self, exc_type, exc_val, exc_tb):
            print('退出...')
            self.file.close()
            return True
            # retuen False
    
    with MyOpen("a.txt")as f:
        # 23+'34'
        print(f)
        print(f.file.read())
        
    

      



  • 相关阅读:
    pandas基本操作
    MySQL数据库(五)使用pymysql对数据库进行增删改查
    MySQL数据库(四)多表查询
    MySQL数据库(三)索引总结
    MySQL数据库(二)-数据库的增删改查
    MySQL数据库(一)
    Linux 解压/压缩xxx.zip格式(unZip Zip的安装和使用)
    关系型数据库和非关系型数据库的对比
    进程、线程、协程的区别
    python迭代器与生成器详解
  • 原文地址:https://www.cnblogs.com/ioipchina/p/11266578.html
Copyright © 2011-2022 走看看