博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

组合,面向对象的内置函数,反射

Posted on 2021-12-07 20:34  ~sang  阅读(24)  评论(0)    收藏  举报

组合

  组合就是一个对象拥有一个属性,该属性的值是另外一个对象。组合与继承都是用来解决代码的重用性问题。不同的是:继承是一种“是”的关系,比如老师是人、学生是人,当类之间有很多相同之处,应该使用继承;而组合则是一种“有”的关系,比如老师有生日,老师有多门课程,当类之间有显著不同,并且较小的类是较大的类所需要的组件时,应该使用组合

class People():
    school = 'SH'

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

class Admin(People):
   pass

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

python = Course('python', '6mon', 10000)
linux = Course('linux', '5mon', 20000)

class Student(People, Course):
    def __init__(self, name, age, gender, course=None):
        if course is None:
            course = []
        self.courses = course
        super().__init__(name, age, gender, )

    def choose_course(self, stu_obj, course):
        stu_obj.courses.append(course)

# stu = Student('ly', 19, 'male', 'python', '6mon', 1000)
# print(stu.course_name)
stu = Student('ly', 20, 'male')
stu.courses.append(python.name)
stu.courses.append(linux.name)
# ['python','linux']
print(stu.courses)

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

    def score(self, stu_obj, score):
        stu_obj.score = score

tea = Teacher('ly', 19, 'male', 10)
tea.course = linux
print(tea.course.name)
print(tea.course.price)
print(tea.course.period)

面向对象的内置函数

  上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法

  __exit__()中的三个参数分别代表异常类型,异常值和追溯信息,with语句中代码块出现异常,则with后的代码都无法执行

  出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量,with中代码块执行完毕时执行__exit__

class Student():
    school = 'SH'

    # 调用类的时候触发
    def __init__(self, name, age):
        self.name = name
        self.age = age

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

    # 打印对象的时候,自动触发的函数
    # 返回值只能是字符串
    def __str__(self):
        return 'name:%s' % self.name
        return 123

stu = Student('ly', 20)
print(stu)  # print(stu.__str__())

f = open('a.txt', mode='w')
print(f)

# __del__
class Student():
    school = 'SH'

    # 调用类的时候触发
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.f = open('a.txt', 'r')

    # 1. 手动执行del
    # 2. 程序执行完毕触发
    def __del__(self):
        print('__del__')
        self.f.close()

stu = Student('ly', 19)
# del stu.name
print('end=>>>>>>>>>>>>')

# __enter__ __exit__
class Open:
    def __init__(self,name):
        self.name=name

    def __enter__(self):
        print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
        # return self
        return 123
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('with中代码块执行完毕时执行我啊')


with Open('a.txt') as f:
    print('=====>执行代码块')
    print(f)
    print(f,f.name)

class Foo:

    def __init__(self):
        pass
    
    # 对象加括号自动触发
    def __call__(self, *args, **kwargs):
        print('__call__')


obj = Foo()  # 执行 __init__

# 一切皆对象
obj()

a = list([1, 2, 3])
# a.append(4)  # list.append(a, 4)
list.append(a, 5)
print(a)

反射

  反射:通过字符串来操作类或者对象的属性

  四个内置函数

    1.hasattr()  判断一个对象中是否有某个属性或方法

      print(p,'print_name')  p是对象,print_name是方法  True或False

    2.getattr()  通过字符串获取对象中的属性或方法

      print(getattr(p,'print_name'))  函数内存地址

      getattr(p,'print_name')()  调用

    3.setattr()  通过字符串设置对象的属性或方法

      setattr(p,'sex','男')  设置属性

    4.delattr()  通过字符串删除对象的属性或方法

      delattr(p,'name')  通过反射删除name属性