面向对象 - 多态、鸭子类型、组合、内置方法

一:组合

继承:is - a
组合:has - a
 

把另外一个类的对象 赋值给当前对象的属性,表达的是什么 有 什么的关系

class Teacher:
    def __init__(self, name, age, gender, level):
        self.name = name
        self.age = age
        self.gender = gender
        self.level = level

    def tell(self):
        print(f'姓名:{self.name},年龄:{self.age},性别:{self.gender},等级:{self.level}')


class Student:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

    def tell(self):
        print(f'姓名:{self.name},年龄:{self.age},性别:{self.gender}')


class Course:
    def __init__(self, name, price, period):
        self.name = name
        self.price = price
        self.period = period

    def tell(self):
        print(f'课程名:{self.name},价格:{self.price},周期:{self.period}')


teacher_obj1 = Teacher('egon', 78, 'male', 5)
student_obj1 = Student('xxq', 18, 'male')

python = Course("python全栈", 29999, "6months")
linux = Course("linux课程", 19999, "3months")

teacher_obj1.courses = [python, linux]
student_obj1.course = python

# tea,stu  # 超级对象

# stu1.course.tell()
for course_obj in teacher_obj1.courses:
    course_obj.tell()
    
# 课程名:python全栈,价格:29999,周期:6months
# 课程名:linux课程,价格:19999,周期:3months
 

继承 + 组合 ==组合技==

# 组合:把另外一个类的对象赋值给当前对象的属性
# 组合表达的是一种有的关系
# class People(object):
class People:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender


class Teacher(People):
    def __init__(self, name, age, gender, level):
        # super(Teacher, self).__init__(name, age, gender)
        super().__init__(name, age, gender)
        self.level = level

    def tell(self):
        print(f'姓名:{self.name},年龄:{self.age},性别:{self.gender},等级:{self.level}')


class Student(People):
    def __init__(self, name, age, gender):
        # super(Student, self).__init__(name, age, gender)
        super().__init__(name, age, gender)

    def tell(self):
        print(f'姓名:{self.name},年龄:{self.age},性别:{self.gender}')


# class Course(People):
class Course:
    def __init__(self, name, price, period):
        # super(Course, self).__init__(name)
        self.name = name
        self.price = price
        self.period = period

    def tell(self):
        print(f'课程名:{self.name},价格:{self.price},周期:{self.period}')


teacher_obj1 = Teacher('egon', 78, 'female', 10)
student_obj1 = Student('xxq', 18, 'male')

python = Course("python全栈", 29999, "6months")
linux = Course("linux课程", 19999, "3months")

teacher_obj1.courses = [python, linux]
student_obj1.course = python

# 这时候teacher_obj1和student_obj1就是超级对象

for course_obj in teacher_obj1.courses:
    course_obj.tell()

student_obj1.tell()
teacher_obj1.tell()


# 课程名:python全栈,价格:29999,周期:6months
# 课程名:linux课程,价格:19999,周期:3months
# 姓名:xxq,年龄:18,性别:male
# 姓名:egon,年龄:78,性别:female,等级:10
 

二:多态

 

什么是多态:同一种事物有多重形态

 

多态性指的是:可以在不考虑对象的具体类型情况下 直接使用对象

class Animal:
    def roar(self):
        pass


class Pepple(Animal):
    def roar(self):
        print('嘤嘤嘤~')


class Dog(Animal):
    def roar(self):
        print('汪汪汪~')


class Cat(Animal):
    def roar(self):
        print('喵喵喵~')


people_obj = Pepple()
dog_obj1 = Dog()
cat_obj1 = Cat()

people_obj.roar()
# 嘤嘤嘤~

dog_obj1.roar()
# 汪汪汪~

cat_obj1.roar()
# 喵喵喵~
 

三:鸭子类型

 

在Python中,只要你长得像鸭子,并且也是嘎嘎叫的,那你就是一只鸭子

# Python推崇的是鸭子类型

class Cpu:
    def read(self):
        print('cpu read')

    def write(self):
        print('cpu write')


class Mem:
    def read(self):
        print('Mem read')

    def write(self):
        print('Mem write')


class Txt:
    def read(self):
        print('Txt read')

    def write(self):
        print('Txt write')


obj1 = Cpu()
obj2 = Mem()
obj3 = Txt()

obj1.read()
obj2.read()
obj3.read()
 

四:面向对象 高级

 

内置方法 __len_

Python中len的精妙之处
# len('hello')
# len([1, 2, 3])
# len({'name': 'xxq', 'age': 18})

# print('hello'.__len__())
# print([1, 2, 3].__len__())
# print({'name': 'xxq', 'age': 18}.__len__())


def my_len(val):
    return val.__len__()


print(my_len('hello'))
print(my_len([1, 2, 3]))
print(my_len({'name': 'xxq', 'age': 18}))
 

__str__会在打印对象的时候触发,然后将返回值(必须是字符串类型)当做本次打印的结果输出

class People:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        print('运行了')
        return 'hahahah'


obj = People('xxq', 18)
print(obj)
# 运行了
# hahahah

obj1 = int(10)
print(obj1)
# 10

print(obj.__str__())
# 运行了
# hahahah

print(obj)  # <'辣白菜同学':18>
# 运行了
# hahahah
 

__del__会在对象执行结束,系统要回收资源的时候触发

class People:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.x = open('a.txt',mode='w')
        # self.x = 占据的是操作系统资源

    def __del__(self):
        # print('run...')
        # 发起系统调用,告诉操作系统回收相关的系统资源
        self.x.close()

obj = People('辣白菜同学', 18)
# del obj # obj.__del__()
print('============>')
 

五:一切皆对象

isinstance(obj,cls)判断对象obj是否是类cls的对象

issunclass(sub,super)判断sub类是否是super类的子类或者子子类

 

六:反射

 

1.什么是反射?

指的是在程序运行过程中可以“动态(不见棺材不落泪)”获取对象的信息(数据属性、函数属性)
# 静态:在定义阶段就确定类型
# 动态:在调用阶段才去确定类型
 

2.如何实现反射?

 

① 先通过多dir:查看某一个对象下 可以.出哪些属性来

dir(对象)可以看出该对象可以.出哪些属性
print(dir(obj))     #  ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name', 'say']
 

② 可以通过字符串反射到真正的属性上,得到属性值

print(obj.__dict__['name'])     # xxq
print(obj.__dict__[dir(obj)[-2]])     # xxq
 

dir(对象)可以看出该对象可以.出哪些属性

 

3.通过字符串来操作属性

 

3.1.hasattr()

print(hasattr(obj, 'name'))     # True
print(hasattr(obj, 'x'))        # False
 

3.2.getattr()

print(getattr(obj, 'name'))     # xxq
print(getattr(obj, 'x'))        # AttributeError: 'People' object has no attribute 'x'
 

3.3.setattr()

print(getattr(obj, 'name', 'EGON'))     # 修改名字为EGON
print(obj.name)                 # EGON
 

3.4.delattr()

delattr(obj, 'name')
print(obj.__dict__)     # {'age': 18}
 

获取对象和类

res1 = getattr(obj, 'say')      # obj.say
res2 = getattr(People, 'say')      # People.say
print(res1)     # <bound method People.say of <__main__.People object at 0x0167B0B8>>
print(res2)     # <function People.say at 0x016783D0>
 

查看是否有这个方法

obj = 10
if hasattr(obj, 'x'):
    print(getattr(obj, 'x'))
else:
    print('找不到')      # 找不到

print(getattr(obj, 'x', None))   # None

print(getattr(People, 'say', None))   # <function People.say at 0x01AC83D0>

if hasattr(obj, 'x'):
    setattr(obj, 'x', 1111111)      # 10.x = 1111111
else:
    print('找不到')  # 找不到
 

基于反射可以十分灵活地操作对象的属性,比如将用户交互的结果反射到具体的功能执行

class Ftp:
    def upload(self):
        print('正在上传')

    def download(self):
        print('正在下载')

    def interactive(self):
        method = input('>>>: ').strip()  # method = 'upload'

        if hasattr(self, method):
            getattr(self, method)()

        else:
            print('该指令不存在!')


obj = Ftp()
obj.interactive()
 

七:了解知识点(abc模块)

import abc

# 指定metaclass属性将类设置为抽象类,抽象类本身只是用来约束子类的,不能被实例化
class Animal(metaclass=abc.ABCMeta):  # 统一所有子类的方法
    @abc.abstractmethod     # 该装饰器限制子类必须定义有一个名为talk的方法
    def say(self):
        print('动物基本的发声...', end='')


class People(Animal):   # 但凡继承Animal的子类都必须遵循Animal规定的标准
    pass


class Dog(Animal):
    pass


class Pig(Animal):
    pass


obj1 = People()
obj2 = Dog()
obj3 = Pig()

obj1.say()  # 动物基本的发声...卧槽
obj2.say()  # 动物基本的发声...汪汪汪
obj3.say()  # 动物基本的发声...吼吼吼

# 若子类中没有一个名为talk的方法则会抛出异常TypeError,无法实例化
# TypeError: Can't instantiate abstract class People with abstract methods say
class Animal(metaclass=abc.ABCMeta):  # 统一所有子类的方法
    @abc.abstractmethod
    def say(self):
        print('动物基本的发声...', end='')


class People(Animal):
    def say(self):
        super().say()
        print('卧槽')


class Dog(Animal):
    def say(self):
        super().say()
        print('汪汪汪')


class Pig(Animal):
    def say(self):
        super().say()
        print('吼吼吼')


obj1 = People()
obj2 = Dog()
obj3 = Pig()

obj1.say()  # 动物基本的发声...卧槽
obj2.say()  # 动物基本的发声...汪汪汪
obj3.say()  # 动物基本的发声...吼吼吼
posted @ 2020-08-15 11:52  Οo白麒麟оΟ  阅读(199)  评论(0编辑  收藏  举报