04. 组合、多态、内置方法、反射

一、组合

1、 组合就是将另一个类的对象赋值给当前对象的属性
对象表示一种“有”’的关系
继承表示一种“是”的关系

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

    def tell(self):
        print("%s:%s" % (self.name, self.age))


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


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

    def tell(self):
        print('<%s:%s:%s>' % (self.name, self.price, self.period))


tea1 = Teacher("egon", 20, "male", 10)
stu1 = Student("cc", 18, "male")

python = Course("python开发", 30000, "3mons")
linux = Course("linux课程", 30000, "3mons")

tea1.courses = [python,linux]
stu1.course = python

此时对象teacher1集对象独有的属性、Teacher类中的内容、Course类中的内容于一身(都可以访问到),是一个高度整合的产物——超级对象

二、多态

2.1 多态性

同一种事物有多种形态,(如动物类有人类、鸟类、爬行动物类等多种类)

我们可以在不考虑某一种对象的具体类型的前提下,直接使用该对象
即:父类有的功能,子类一定有

class Animal: #同一类事物:动物
    def talk(self):
        pass
class Cat(Animal): #动物的形态之一:猫
    def talk(self):
        print('喵喵喵')
class Dog(Animal): #动物的形态之二:狗
    def talk(self):
        print('汪汪汪')
class Pig(Animal): #动物的形态之三:猪
    def talk(self):
        print('哼哼哼')
cat = Cat()
dog = Dog()
pig = Pig()

cat.talk()  # 喵喵喵
dog.talk()  # 汪汪汪
pig.talk()  # 哼哼哼

更进一步,我们可以设置一个统一的接口来使用

def talk(animal):
	animal.talk()
talk(cat)
talk(dog)
talk(pig)

python中一切皆对象,本身就支持多态性

# 我们可以在不考虑三者类型的情况下直接使用统计三个对象的长度
s.__len__()
l.__len__()
t.__len__()

# Python内置了一个统一的接口
len(s)
len(l)
len(t)

2.2 metaclass方法

多态性的本质就是不同的子类中定义有相同的方法名,这样我们就可以不考虑类而统一使用一种方式去使用对象,
可以在父类中引入抽象类的方法来限制子类中必须有某些方法名

import abc
# 指定metaclass属性将类设置为抽象类,抽象类本身只是用来约束子类的,不能被实例化
class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod # 该装饰器限制子类必须定义有一个名为talk的方法
    def talk(self): # 抽象方法中无需实现具体的功能
        pass

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

cat=Cat() # 若子类中没有一个名为talk的方法则会抛出异常TypeError,无法实例化

Animal 类的作用就是相当于一个标准,它不能被实例化

2.3 总结

使用多态性的好处:

1.增加了程序的灵活性
  以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal)
2.增加了程序额可扩展性
  通过继承animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(animal)去调用   

2.4 鸭子类型

python崇尚鸭子类型,即‘如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’
python程序员通常根据这种行为来编写程序。例如,如果想编写现有对象的自定义版本,可以继承该对象
也可以创建一个外观和行为像,但与它无任何关系的全新对象,后者通常用于保存程序组件的松耦合度。

三、一切皆对象

在python3中,
数据类型==类

print(int)  # <class 'int'>

如内置的list:

x = [1, 2, 3]  # list([1,2,3])  x就是类list实例化的对象

x.append(4)  # 等同于list.append(x,4), 调用的是list类的方法list.append(self, __object)

四、内置函数

4.1 isinstance(obj, cls)

检查obj是否是类cls的对象

print(isinstance(10, int))   # True

4.2 issubclass(sub, super)

检查sub类是否是super类的派生类

class People:
	pass
class Student(People):
	pass
	
print(issubclass(Student, People))  # True

五、内置方法

内置方法都是在满足某种条件自动调用的,

5.1 str

用于改变对象的字符串显示
返回值必须是字符串

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

    def __str__(self):
        return f"姓名:{self.name}  年龄:{self.age}"

p1 = People('cc', 18)
print(p1)  # 姓名:cc  年龄:18

5.2 del

构析方法,用于当对象在内存中被释放时,自动触发运行
ps:

如果产生的对象只是python语言级别的,那么无序定义__del__,
如果产生的对象同时还会向操作系统发起系统调用,(一个对象同时有用户级和内核级两种资源),那么必须在清除对象的同时回收系统资源
class Foo:
    def __init__(self, name, age, f):
        self.name = name
        self.age = age
        self.f = f

    def __del__(self):
        print('回收资源')
        self.f.close()

obj = Foo('cc', 18, open('a.txt', 'r', encoding='utf-8'))  # 回收资源(程序运行完毕后自动调用__del__)
print('运行完毕...')
# 结果:
'''
运行完毕...
回收资源
'''

六、反射

反射:是指程序可以访问、检测和修改它本身状态或行为的一种能力
python面对对象中的反射:
通过字符串的形式操作对象相关的属性,python中的一切事物都是对象,都可以使用反射
四个可以实现自省的函数:
注意:

属性的名字必须使用字符串形式(这四个函数都相当于是在操作对象属性字典的key 和value来实现功能的)

6.1 hasattr(object, name)

判断对象是否有某种属性

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


f1 = Foo('cc', 18)

print(hasattr(f1, 'name'))  # True

6.2 getattr(object, name, default = None)

获取对象的属性,如果属性不存在就报错,
可以自定义找不到时返回的值,比如None

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

obj = Foo('cc', 18)
print(getattr(obj, 'name', None))  # cc   

6.3 setattr(object, name, value)

设置对象属性,属性存在就修改,没有就添加

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


obj = Foo('cc', 18)
setattr(obj, 'name', 'jason')
setattr(obj, 'sex', 'male')
print(obj.__dict__)  # {'name': 'jason', 'age': 18, 'sex': 'male'}

6.4 delattr(object, name)

用于删除对象的属性,属性不存在会报错

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


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

obj对象的age属性已经被删除

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值