二十三、多态、内置方法和魔术方法,上下文管理,

一、多态

"""多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承)
定义:多态是一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的结果
好处:调用灵活,有了多态,更容易编写出通用的代码,做出通用的编程,以适应需求的不断变化
实现步骤:
1.定义父类,并提供公有方法
2.定义子类,并重写父类方法
3.传递子类对象给调用者,可以看到不同子类执行效果不同
"""
# 需求:警务人员和警犬一起工作,警犬分为两种:追击敌人和追查毒品,携带不同的警犬,执行不同的任务
# 1. 定义父类

class Dog(object):

    def work(self):
        pass


# 2.定义子类,子类重写父类方法:定义两个类表示不同的警犬
class Armydog(Dog):
    def work(self):
        print("追击敌人")


class Drugdog(Dog):
    def work(self):
        print("追查毒品")


# 定义人类
class Person:
    def work_with_dog(self, dog):
        dog.work()


# 3.创建对象,调用不同功能,观察不同结果

ad = Armydog()
du = Drugdog()
p = Person()
p.work_with_dog(ad)

二、内置方法

对象/类.__dict__ 对象或类的对象属性名称
对象/类__class__对象或类的类属性名称
类.mro() 查看继承关系,第一个到最后一个
类/cls.__name__ 类名称
类.__base__ 继承的类
# 双下方法
# __str__  魔术方法
# __repr__

class Teacher:
    def __init__(self, name, salary):
        self.name = name
        self.salary = salary

    def __str__(self):
        return "Teacher is object :%s" % self.name  # 在__str__返回值必须是字符串,否则报错

    def __repr__(self):
        return str(self.__dict__)

    def func(self):
        return "wahaha"


t = Teacher("shabi", 10)
print(t)  # 打印一个对象的时候,就是调用t.__str__
print(repr(t))
print(">>>>>>>%r" % t)


# a.__str__>>>>>>>>>>>cbject
# %s str () 直接打印实际上都是走的__str__
# %s repr()  实际上都是走的__repr__
# repr 是str的备胎,但是str不能做repr的备胎

# print(obj)/%s'%obj/str(obj)的时候,实际上调用了obj.__str__方法,如果str方法有,那么返回的必定是一个字符串
# 如果没有__str__方法,会先找本类中的__repr__方法,再没有,再找父类中的__str__
# repr(),只会找__repr__,如果没有找父类


# __len__方法
# class Classes:
#     def __init__(self, name):
#         self.name = name
#         self.student = []
#
#     def __len__(self):
#         return len(self.student)
#
#
# py_q10 = Classes("python 脱产九期")
# py_q10.student.append("都比")
# py_q10.student.append("傻冒")
# print(len(py_q10))


# __del__方法
# class A:
#     def __del__(self):  # 析构函数;在删除对象之前进行收尾工作
#         self.f.close()
#
#
# a = A()
# a.f = open()  # 打开文件,第一 在操作系统中打开一个文件,拿到文件操作符存在了内存中
# del a  # 既删除变量,又执行方法,先执行方法,后删除


# 已经删除,报错

# __call__
class A:
    def __init__(self, name):
        self.name = name

    def __call__(self):
        print("执行我啦")


a = A("alex")
a()  # 执行我啦
三、item系列
__getitem__\__setitem__\__del__item
class Foo:
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

        # 获取

    def __getitem__(self, item):
        if hasattr(self, item):
            return self.__dict__[item]
        # 设置,修改

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

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


f = Foo("tank", 18, "")
print(f["name"])  # tank
print(f["age"])  # 18
f["hobby"] = ""
print(f.hobby, f["hobby"])
# del f["hobby"]  # 删除
print(f.__dict__)

四、上下文管理

当执行with 语句时,会先执行enter ,
#
# 当代码执行完毕后执行exit,或者代码遇到了异常会立即执行exit,并传入错误信息
#
# 包含错误的类型.错误的信息.错误的追踪信息
#
# 注意:
#
# ```python
# enter 函数应该返回对象自己
# exit函数 可以有返回值,是一个bool类型,用于表示异常是否被处理,仅在上下文中出现异常有用
# 如果为True 则意味着,异常以及被处理了
# False,异常未被处理,程序将中断报错
class Myopen:
    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.........")
        self.file.close()
        return True


# m =Myopen("txt")  和下面同等
with Myopen("txt") as m:
    res = m.file.read()
    print(res)

 

posted @ 2019-07-29 15:40  凯帅  阅读(191)  评论(0编辑  收藏  举报