zoukankan      html  css  js  c++  java
  • Python 多态 对象常用内置函数 运算符重载 对象迭代器 上下文管理

    一 多态

    1.什么是多态:多态不是一个具体的技术或代码。指的时候多个不同类型对象可以响应同一个方法,产生不同的结果。

    2.使用多多态的好处:提高了程序的灵活性,拓展性

    3.如何实现:鸭子类型 就是典型的多态 多种不同类型 使用方法一样

    4.案例

    class Cat():
        def bark(self):
            print("喵喵喵")
        def run(self):
            print("四条腿跑!")
        def sleep(self):
            print("趴着睡!")
            
    class Pig():
        def bark(self):
            print("哼哼哼!")
        def run(self):
            print("四条腿跑!")
        def sleep(self):
            print("侧躺着睡!")
    
    # 一个用来管理动物的方法   只要你传入是一个动物 我就按照动物的标准来使用 完全不用考虑你具体是什么类型
    def management_animal(animal):
        print("==================正在溜%s=============" % animal.__class__.__name__)
        animal.bark()
        animal.run()
        animal.sleep()
    View Code

    二 isinstance(参数1,参数2)内置函数

    1.判断一个对象是否是某个类的实例,结果为布尔类型

    参数1 要判断的对象

    参数2 要判断的类型

    2.案例:

    a = isinstance('own',str) # 判断对象是否字符串类型
    print(a) # True 
    
    def add_num(a,b):
        if isinstance(a,int) and isinstance(b,int): # 判断是否是整型
            return a+b
        return None
    print(add_num(20,10)) # 30
    View Code

    三  issubclass(参数1,参数2)内置函数

    1.判断一个类是否是另一个类的子类。

    参数一是子类

    参数二是父类

    2.案例:

    class Animal:
        def eat(self):
            print("动物得吃东西...")
    
    class Pig(Animal):
        def  eat(self):
            print("猪得吃 猪食....")
    
    a = issubclass(Pig,Animal)
    print(a) # True
    
    p = Pig()
    b = issubclass(type(p),Animal)
    print(b) # True
    
    # 拓展
    print(type(p),p.__class__) # <class '__main__.Pig'> <class '__main__.Pig'>
    View Code

    四 对象常用内置函数

    __str__()

    1.触发时机:在将对象转为字符串时执行 。注意:返回值必须为字符串类型。

    2.使用场景:子类可以覆盖该方法来完成 对打印内容的自定义

    3.该方法在object中有定义 默认行为 返回对象类型以及地址 <__main__.Person object at 0x0000016F450C7390>

    class Person:
        def __init__(self,name,age):
            self.name = name
            self.age = age
        # 将对象转换为字符串时执行r
        def __str__(self):
            print("str run")
            return "my name is %s , age is %s" % (self.name,self.age)
    p = Person("rose",20)
    
    print(p) #在打印前都会现将要打印的内容转为字符串  通过调用__str__函数
    
    q = str(p)
    print(q)
    View Code

    __del__()

    1.触发时机:手动删除对象时立马执行,或是程序运行结束时也会自动执行

    2.使用场景:当你的对象在使用过程中,打开了不属于解释器的资源:例如文件,网络端口

    3.注意:该函数不是用来删除对象的

    # del使用案例
    
    class FileTool:
        """该类用于简化文件的读写操作 """
    
        def __init__(self,path):
            self.file = open(path,"rt",encoding="utf-8")
            self.a = 100
    
        def read(self):
            return self.file.read()
    
        # 在这里可以确定一个事,这个对象肯定不使用了 所以可以放心的关闭问文件了
        def __del__(self):
            self.file.close()
    
    
    tool = FileTool("a.txt")
    print(tool.read())
    View Code

    __call__()

    1.触发时机:在调用对象时自动执行,(既对象加括号)

    #call 的执行时机
    class A:
        def __call__(self, *args, **kwargs):
            print("call run")
            print(args)
            print(kwargs)
    
    a = A()
    a(1,a=100) # call run (1,) {'a': 100}
    View Code

    __slots__

    该属性是一个类属性,用于优化对象内存占用
    优化的原理,将原本不固定的属性数量,变得固定了
    这样的解释器就不会为这个对象创建名称空间,所以__dict__也没了  
    从而达到减少内存开销的效果

    另外当类中出现了slots时将导致这个类的对象无法在添加新的属性

    # slots的使用
    import sys
    class Person:
    
        __slots__ = ["name"] # 对象中只能添加'name'的属性,添加其他报错
        def __init__(self,name):
            self.name = name
    
    p =  Person("jck")
    
    # 查看内存占用
    print(sys.getsizeof(p)) # 48
    # p.age = 20 # 无法添加
    
    # dict 没有了
    print(p.__dict__)  # 报错 因为类中有__slots__ 所以__dict__不存在了
    View Code

    __getattr__()   __setattr__()   __delattr__()

    __getattr__()

    1.执行时机:对象用点访问属性的时候,如果属性不存在时执行(无论是类中的属性还是对象中属性)

    class A:
        def __getattr__(self, item):
            print("__getattr__")
            return 1
    a = A()
    print(a.name) # __getattr__ 1
    View Code

    __getattribute__()

    1.getattribute 该函数也是用来获取属性
    在获取属性时先执行__getattribute__()。如果属性存在执行完__getattribute__()则不再执行__getattr__(),如果属性不存在执行完__getattribute__()则再执行__getattr__()。

    class A:
    
         def __getattr__(self, item):
            print("__getattr__")
            return 1
         def __getattribute__(self, item):
            print("__getattribute__")
            # return self.__dict__[item]
            return super().__getattribute__(item)
    a = A()
    print(a.name) # __getattribute__ __getattr__ 1
    
    a.name = 'jack'
    print(a.name) # __getattribute__ jack
    View Code

    __setattr__()

    1.执行时机:对象用点设置属性时(无论是添加还是修改)

    class A:
        def __setattr__(self, key, value):
            print(key) # name
            print(value) # jack
            print("__setattr__")
            self.__dict__[key] = value
    
    a = A()
    a.name = "jack" # name jack __setattr__
    View Code

    __delattr__()

    1.执行时机:用del 对象.属性  删除属性时 执行(属性要先存在)

    class A:
         def __delattr__(self, item):
            print("__delattr__")
            print(item)
            self.__dict__.pop(item)
            pass
    a = A()
    a.name = "jack"
    del a.name # __delattr__  name
    View Code

    [] 的实原理

    getitem setitem delitem

    __geitem__()

    1.执行时机:当对象用中括号去获取属性时执行(不管属性存在还是不存在)

    class A:
        def __getitem__(self, item):
            print("__getitem__")
            return self.__dict__[item]
    a = A()
    a.name = "jack"
    print(a["name"]) #  "jack"
    View Code

    __setitem__()

    1.执行时机:当对象用括号去设置属性时 执行

    class A:
            def __setitem__(self, key, value):
            print("__setitem__")
            self.__dict__[key] = value
    a = A()
    a["name"] = "jack" # __setitem__
    View Code

    __delitem__()

    1.执行时机:当对象用中括号去删除属性时 执行

    class A:
            def __delitem__(self, key):
            del self.__dict__[key]
            print("__delitem__")
    a = A()
    a.name = "jack"
    del a["name"] # __delitem__
    View Code

    五 运算符重载(对象大小比较)与迭代器

    class Student(object):
        def __init__(self,name,height,age):
            self.name = name
            self.height = height
            self.age = age
    
        def __gt__(self, other):
            # print(self)
            # print(other)
            # print("__gt__")
            return self.height > other.height
        
        def __lt__(self, other):
            return self.height < other.height
    
        def __eq__(self, other):
            if self.name == other.name and  self.age == other.age and self.height == other.height:
                return True
            return False
    
    stu1 = Student("jack",180,28)
    stu2 = Student("jack",180,28)
    # print(stu1 > stu2) # 触发 __gt__(self, other)
    # print(stu1 < stu2) # 触发 __lt__(self, other)
    print(stu1 == stu2) #  # 触发 __eq__(self, other)
    上述代码中,other指的是另一个参与比较的对象,
    
    大于和小于只要实现一个即可,符号如果不同  解释器会自动交换两个对象的位置 ,只能在同一个类中比较
    View Code
    # 实现一个自定义的range
    
    
    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,10,2):
        print(i) # 1 3 5 7 9
    View Code

    六 上下文管理

    当执行with 语句时,会先执行enter ,
    
    当代码执行完毕后执行exit,或者代码遇到了异常会立即执行exit,并传入错误信息
    
    包含错误的类型.错误的信息.错误的追踪信息  
    注意:
        enter 函数应该返回对象自己 
        exit函数 可以有返回值,是一个bool类型,用于表示异常是否被处理,仅在上下文中出现异常有用
        如果为True 则意味着,异常以及被处理了 
        False,异常未被处理,程序将中断报错
    
    class MyOpen(object):
    
    
        def __init__(self,path):
            self.path = path
    
        def __enter__(self):
            self.file = open(self.path)
            print("enter.....")
            return self
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            print("exit...")
            # print(exc_type,exc_val,exc_tb)
            self.file.close()
            return True
    
    
    with MyOpen("a.txt") as m:
        print(m) # enter.....  <__main__.MyOpen object at 0x0000015CD88B84E0> exit...
    View Code
  • 相关阅读:
    bzoj1045: [HAOI2008] 糖果传递(数论)
    bzoj1083: [SCOI2005]繁忙的都市(最小生成树)
    bzoj1079: [SCOI2008]着色方案(DP)
    BZOJ2467 [中山市选2010]生成树
    BZOJ4766 文艺计算姬
    BZOJ4894 天赋
    BZOJ2560 串珠子
    [SDOI2014]重建
    BZOJ3622 已经没有什么好害怕的了
    [SDOI2016]储能表
  • 原文地址:https://www.cnblogs.com/tfzz/p/11266478.html
Copyright © 2011-2022 走看看