面向对象-高级

一、多态

  多态:指的是某种事物存在多种形态,例如:动物有:人 狗 猪

在程序中多态指的是,不同对象可以响应相同的方法,并可以有自己不同的实现方法

使用多态的好处:

    1:增加了程序的灵活性 (以不变应万变,不论对象千变万化,使用者都是同一种形式去调用)

    2:增加了程序的可扩展性(通过继承后再创建新的类)

实现多态:

  接口 抽象 鸭子类型(拥有相似的属性和方法)都可以写出具备多态的代码

  多态 鸭子类型
class Ji:
    def bark(self):
        print("gege")
    def spawm(self):
        print("下鸡蛋")
class Duck:
    def bark(self):
        print("gaga")
    def spawm(self):
        print("下鸭蛋")
class EI:
    def bark(self):
        print("eeee")
    def spawm(self):
        print("下鹅蛋")

j=Ji()
d=Duck()
e=EI()

# j.spawm()
# d.spawm()
# e.spawm()

def manage(obj): # 管理同样属性的功能
    obj.spawm()
manage(j)
manage(d)
manage(e)
"pyhton中到处都有多态的现象"
a=100
b="Gavin"
c=0.12355
d={'name':"jack",'age':20}
e=(12,45,54)
print(type(a))
print(type(b))
print(type(c))
print(type(d))
print(type(e))

>>>
<class 'int'>
<class 'str'>
<class 'float'>
<class 'dict'>
<class 'tuple'>

 二、oop相关内置函数

  1、isinstance(obj,cls):判断一个对象是否是某个类的对象  (判断类型的方法)

def add_num(a,b):
if isinstance(a,int) and isinstance(b.int): #判断是否是整型
  return a+b
return None
a="100"
b=100
print(add_num(a,b))

# 判断是否是什么类型

  2、issubclass(sub,super):判断一个类是否是另一个类的子类

class Animai:
    print("动物都能动...")
class Pig(Animai):
    def eat(self):
        print("猪都吃猪食...")
class Tree:
    def light(self):
        print("植物的光合作用")
p=Pig()
t=Tree()
def manage(obj):  # 定义一个管理系统
    if issubclass(type(obj),obj): # 判断是不是子类的类
        obj.eat()
    else:
        print("这不是同一类!")
manage(Pig)
manage(t)
print(issubclass(Tree,object))
>>>> 动物都能动... Traceback (most recent call last): 这不是同一类!

三、类中的魔法函数:对象的显示相关函数

  1:__str__ 会在对象被转换为字符串时,转换的结果就是这个函数的返回值

使用的场景:可以利用该函数来自定义,对象的是打印格式。

class Person:
    def __str__(self):   #转换为字符串
        print("run")
       return "abc"  
p=Person()
print(p)


>>
run
abc
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)
            pass   # 
p=person()
print(p)

>>>   这是一个person对象 name:sore age:20

# 执行结果会覆盖——init——内置方法 执行打印的格式

  2:__del__ 当手动删除对象时立马执行,或是程序运行结束时也会自动执行

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

import time

class Person:
    def __init__(self,name,age):
        self.name=name
        self.age=age
def __del__(self):
    print("del run ")
p=person("reso",20)
time.sleep(2)

print("结束运行!")

 __del__使用案例

# 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())

3:__call__ 执行时机:在调用对象时自动执行(即对象+括号)对象=类名()

#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}

4:__slots__  :该属性是一个类属性,用于优化对象内存占用

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

当类中出现了slots时 将导致这个类的对象无法在添加新的属性,开辟的内存空间地址

# slots的使用
class Person:
    __slots__ = ["name"]  # 只固定开辟 name的内存空间 优化内存不浪费空间
    def __init__(self,name):
        self.name = name
        print(self.__dict__)
p =  Person("jck")

# print(sys.getsizeof(p))
# p.age = 20

# dict 没有了
print(p.__dict__)

四、属性的getattr setattr 和delattr  getattribute

  点语法.操作对象属性时自动触发

 getattr:使用点语法访问属性的时候如果属性不存在时才执行
 setattr:用点语法设置属性(修改/添加)时触发它的执行
 delattr:使用点语法删除属性时触发

  这几个函数反映了 python解释器时如何让实现 用点来访问属性的

getattribute: 该函数也是用来获取属性的:在获取属性时如果存在gqtattribute 则先执行该函数,如果没有拿到属性则继续调用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 1
    def __getattribute__(self, item):
        print("__getattribute__")
        # return self.__dict__[item]
        return super().__getattribute__(item)
a = A()
a.name = "jack"
print(a.name)

del a.name
print(a.name)
print(a.xxx)
a.name = "xxx"
print(a.name)
>>>>
__setattr__
__getattribute__
__getattribute__
jack
__delattr__
name

 五、[ ] 的原理:

getitem   setitem   delitem 

任何的符号都会被解释器解释成特殊的含义,例如,[ ] ()

getitem 当你用中括号去获取属性时 执行
setitem  当你用中括号去设置属性时 执行
delitem 当你用中括号去删除属性时 执行

 案例:

class A:
    def __getitem__(self, item):
        print("__getitem__")
        return self.__dict__[item]

    def __setitem__(self, key, value):
        print("__setitem__")
        self.__dict__[key] = value

    def __delitem__(self, key):
        del self.__dict__[key]
        print("__delitem__")

a = A()
# a.name = "jack"
a["name"] = "jack"
print(a["name"])
del a["name"]
# print(a["name"])

>>>
__setitem__
__getitem__
jack
__delitem__

六、运算符重载:对象比较大小

  当我们在使用某个符号时,python解释器都会为这个符号定义一个含义,同时调用对应的处理函数,

当我们需要自定义对象的比较规则时,就可以在子类中覆盖 大于 等于 小于 等一系列的方法....

案列:

  原本自定义对象无法直接使用大于、小于来进行比较,我们可自定义运算符来实现,让自定义对象也支持比较云算符

__gt__:大于比较、 def __It__:小于比较、  def__eq__:等于比较

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)
        return self.name>other.name
    def __eq__(self, other): # 比较等于
        print(self)
        print(other)
        if self.name == other.name and self.age == other.age:
            return  True
        return  False
    def __lt__(self, other): # 比较小于
        if self.age<other:
            return
s=Student("reso",20,185)
s1=Student("Jack",18,155)
# print(s.name,s1.age)
print(s>s1)
print(s<s1)
print(s==s1)

>>>>
True
20
NOne   原本类于类之间不能进行比较  通过函数“__gt__  __qe__  __lt__ ” 后可以进行比较

  上述 程序中,other指的是另一个参与比较的对象: 大于和小于只要实现一个即可,

解释器会自动交换两个对象的位置即可

七、迭代器协议

  迭代器是指具__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,10,2):
    print(i)
   

>>>>1 3 5 7 9

实现让range(1,10)for 循环

八。上下文管理:  __enter____exit__

  上下文:context 

  在Python中,上下文可以理解为是一个代码区间,一个范围,例如 witho open  打开的文件仅在这个上下文中有效

涉及的方法:

  enter: 表示进入上下文     exit :  表示退出上下文

当执行with语句时 会先执行enter,当代码执行完毕后执行exit 或者代码遇到了异常会立即执行exit,并传入错误的信息

包含:错误的类型 错误的信息 错误的追踪信息

注意:

enter 函数应该返回对象自己
exit 函数 可以有返回值,是一个bool类型,用于表示异常是否被处理
仅在上下 文中出现异常有用
如果为True则意味着,异常以经被处理了
False,异常未被处理,程序将中断报错

 

 

 

 

 

 

  

posted @ 2019-07-29 20:50  游走De提莫  阅读(201)  评论(0编辑  收藏  举报