|
组合,反射,魔术方法
组合
- 什么是组合?
- 组合就是,一个对象拥有一个属性,该属性的值是另外一个对象.
- """什么场景下使用继承? 什么场景下使用组合?"""
- 继承一般情况用在:什么是什么的情况 is
- 组合一般用在:什么有什么的情况 has
复制代码- class Foo:
- def __init__(self, m):
- self.m = m
- class Bar():
- def __init__(self, n):
- self.n = n
- """一个对象拥有一个属性,该属性的值是另外一个对象."""
- obj=Bar(10)
- obj1 = Foo(20)
- # 超级对象,通过一个属性可以访问到另外一个对象的值
- obj.x=obj1
- print(obj.x.m)
复制代码 案例
- 组合案例:选课
- class People():#父类
- school = 'SH'
- def __init__(self, name, age, gender, course_name=None, course_price=None, course_period=None):
- self.name = name
- self.age = age
- self.gender = gender
- # self.course_name = course_name
- # self.course_price = course_price
- # self.course_period = course_period
- class Admin(People):#管理员
- 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
- python=Course('python', 10000, '6mon')#添加科目
- linux=Course('linux', 20000, '5mon')
- # print(python.name)
- # print(python.price)
- # print(python.period)
- class Student(People):
- #学生
- def __init__(self, name, age, gender, course=None):
- super().__init__(name, age, gender)
- if course is None:
- course = []
- self.course = course
- stu = Student('kevin', 20, 'male')
- stu.course.append(python.name)#进行组合
- stu.course.append(linux.name)#组合
- print(stu.course) # [<__main__.Course object at 0x000001F258F86B80>, <__main__.Course object at 0x000001F258F511C0>]
- # stu.course: []
- for i in stu.course:
- print(i)
- class Teacher(People):#老师
- def __init__(self, name, age, gender, level):
- super().__init__(name, age, gender)
- self.level = level
- tea = Teacher('ly', 19, 'female', 10)
- # print(tea.course_name)
- tea.course=linux#创建一个course,将linux组合
- print(tea.course.period)
- print(tea.course.name)
- print(tea.course.price)
复制代码 反射
- 在Python中,反射指的是通过字符串来操作对象的属性,涉及到四个内置函数的使用(Python中一切皆对象,类和对象都可以用下述四个方法)
- 四个内置函数:
- getattr: 获取属性 ##### 用的最多
- setattr:设置属性
- hasattr:判断是否有某个属性
- delattr:删除
复制代码 getattr 获取属性
- class Student():
- school = 'SH'
- def __init__(self,name, age):
- self.name=name
- self.age = age
- def func(self):
- print('from func')
- def index(self):
- print('from index')
- stu = Student('kevin', 20)
- # attr=input('请输入你要操作的属性名:')
- """反射:就是通过字符串的形式来操作对象的属性"""
- # 1. 获取属性
- """当你查询的属性不存在的时候,如果给了第三个参数,就返回第三个参数"""
- print(stu.school)
- res = getattr(stu, 'school1', 666)
- print(res)
- res1=getattr(stu,'shool',666)
- print(res1)#666
- res2=getattr(stu,'name')
- print(res2)
- ### 函数的用法
- """必须掌握!!!!!!"""
- res=getattr(stu, 'func1', stu.index)#等同于stu.func1,不存在该属性则返回默认值stu.index
- res()
复制代码 setattr:设置属性
- ### 设置
- class Student():
- school = 'SH'
- def __init__(self,name, age):
- self.name=name
- self.age = age
- def func(self):
- print('from func')
- def index(self):
- print('from index')
- stu = Student('kevin', 20)
- setattr(stu, 'x', 666) # stu.x=666
- print(stu.__dict__)#{'name': 'kevin', 'age': 20, 'x': 666}
复制代码 hasattr:判断是否有某个属性
- #判断
- class Student():
- school = 'SH'
- def __init__(self,name, age):
- self.name=name
- self.age = age
- def func(self):
- print('from func')
- def index(self):
- print('from index')
- stu = Student('kevin', 20)
- print(hasattr(stu, 'func'))#True
- print(hasattr(stu,'qwe'))#False
- if hasattr(stu, 'func'):
- getattr(stu, 'func')()
- else:
- pass
复制代码 delattr:删除
- class Student():
- school = 'SH'
- def __init__(self,name, age):
- self.name=name
- self.age = age
- def func(self):
- print('from func')
- def index(self):
- print('from index')
- stu = Student('kevin', 20)
- delattr(stu, 'name')
- print(stu.__dict__)#{'age': 20}
复制代码 魔术方法
init str,repr
- class Student():
- def __init__(self, name, age):
- self.name = name
- self.age = age
- """
- 1. 打印对象的时候,输出对象的时候会自动触发类中得__str__方法
- 2. 返回值必须是字符串形式
- 3. 如果它跟__repr__方法同时存在,__str__的优先级更高
- """
- def __str__(self): # 这个用的是最多的
- print('str')
- return 'from str'
- def __repr__(self):
- print('repr')
- return 'from repr'
- wqe=Student('qwe',12)
- print(wqe)#str from str
- # print('repr:', repr(wqe))
- print('str:', str(wqe))#str str: from str
复制代码 del
- class MySQL:
- def __init__(self, ip, port):
- self.ip = ip
- self.port = port
- self.f = open('a.txt', 'w')
- """
- 1.当你删除对象的时候会触发__del__的执行
- 2. 当整个脚本的程序都执行完毕的时候,也会触发__del__的执行
- 3. 一般用在用来在对象被删除时自动触发回收系统资源的操作
- """
- def __del__(self):
- print('from _del')
- self.f.close()
- mysql = MySQL('127.0.0.1', 3306)
复制代码 issubclass方法用于判断参数 class 是否是类型参数 classinfo 的子类
- class Foo:
- pass
- class Bar(Foo):
- pass
- class Bar1():
- pass
- print(issubclass(Bar1, Foo))
复制代码 __doc__注释无法继承
- class Foo:
- """
- '我是描述信息asdasd'
- '我是描述信息asdasd'
- '我是描述信息asdasd'
- """
- pass
- class Bar(Foo):
- pass
- print(Foo.__doc__)
- # '我是描述信息asdasd'
- # '我是描述信息asdasd'
- # '我是描述信息asdasd'
- print(Bar.__doc__)
- #None
复制代码 enter和exit 上下文管理器with原理
- class Open:
- def __init__(self, name):
- self.name = name
- def __enter__(self):
- print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
- # return self
- def __exit__(self, exc_type, exc_val, exc_tb):
- print('with中代码块执行完毕时执行我啊')
- """with它可以用在很多地方,但是,出现with语句后面的对象中得类必须要声明__enter__和__exit__"""
- with Open('a.txt') as f:
- print('=====>执行代码块')
- print('=====>执行代码块')
- print('=====>执行代码块')
- print('=====>执行代码块')
- print('=====>执行代码块')
- # print(f,f.name)
-
复制代码- 简答题:先聊聊with 的用法? 问with上下文管理协议的执行原理? 为什么打开文件只会可以自动关闭?请说出原因
- class Open:
- def __init__(self, name):
- self.name = name
- def __enter__(self):
- print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
- # return self
- def __exit__(self, exc_type, exc_val, exc_tb):
- print('with中代码块执行完毕时执行我啊')
- print(exc_type) # 异常类型
- print(exc_val) # 异常值
- print(exc_tb) # 追溯信息
- return True # 如果你在这个方法里面返回了True,with代码块中出现了异常,就相当于没有出现异常
- """with它可以用在很多地方,但是,出现with语句后面的对象中得类必须要声明__enter__和__exit__"""
- # with Open('a.txt') as f:
- # print('=====>执行代码块')
- # print('=====>执行代码块')
- # print('=====>执行代码块')
- # print('=====>执行代码块')
- # print('=====>执行代码块')
- # # print(f,f.name)
- """如果with代码块中出现了异常,则with语句之后的代码都不能正常执行"""
- with Open('a.txt') as f:
- print('=====>执行代码块')
- raise AttributeError('***着火啦,救火啊***') # 抛出异常,主动报错
- print('0'*100) #------------------------------->不会执行
复制代码 setattr 设置 ,delattr 删除,getattr查看
点语法
- __setattr__,__delattr__,__getattr__
- class Foo:
- x=1
- def __init__(self,y):
- self.y=y
- """当你找的属性不存在的时候,会触发__getattr__,但是必须是点语法的时候才会"""
- def __getattr__(self, item):
- print('----> from getattr:你找的属性不存在')
- def __setattr__(self, key, value):
- print('----> from setattr')
- # self.key=value # self.a=20
- # self.key=value #这就无限递归了,你好好想想
- self.__dict__[key]=value #应该使用它
- def __delattr__(self, item):
- print('----> from delattr')
- # del self.item #无限递归了
- self.__dict__.pop(item)
- obj=Foo(10)
- # obj.z
- obj.a=20
- print(obj.a)
- del obj.a
复制代码 setitem,getitem,delitem__
中括号取值时
- __setitem__,__getitem,__delitem__
- class Foo:
- def __init__(self, name):
- self.name = name
- """当你通过中括号获取对象的属性的时候,会自动触发__getitem__"""
- def __getitem__(self, item):
- print('__getitem__')
- print(self.__dict__[item])
- def __setitem__(self, key, value):
- # key:age
- # value:18
- print('__setitem__')
- self.__dict__[key] = value
- # self.__dict__['age'] = 18
- def __delitem__(self, key):
- print('del obj[key]时,我执行')
- self.__dict__.pop(key)
- pass
- # def __delattr__(self, item):
- # print('del obj.key时,我执行')
- # self.__dict__.pop(item)
- obj=Foo('tom')
- # print(obj.name)
- # obj['name']
- obj['age'] = 18
- # obj.age=18
- print(obj.age)
- del obj['age']
复制代码 call
- class Foo:
- def __init__(self):
- pass
- #### 当对象加括号的时候会触发__call__的执行
- def __call__(self, *args, **kwargs):
- print('__call__',*args)
- obj=Foo()
- print(obj)#<__main__.Foo object at 0x000002CCFDE2BF70>
- obj('qe')#__call__ qe
复制代码 来源:https://www.cnblogs.com/zhangfanshixiaobai/p/17755797.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
|