一个类可以有多个父类,多继承,难点:super python里用的多的,重写,重新覆盖父类的方法 用父类名字调用父类,浪费资源 用super是先到mro元组里查找对应的调用,再从这个往后一个调用 c3算法确定mor元组。保证每个类只调用一次
class Parents(object): a = 100 def __init__(self, name, *args, **kwargs): print('Parent-------------->Begin') self.name = name print('Parent-------------->End') class Son1(Parents): #这里用*args,**kwargs,不定长参数,是为了避免多继承的报错 def __init__(self, age, name, *args, **kwargs): print('Son1------------>Begin') self.age = age # Parents.__init__(self, name) super(Son1, self).__init__(name, *args, **kwargs) print('Son1------------>End') class Son2(Parents): def __init__(self, sexy, name, *args, **kwargs): print('Son2------------>Begin') self.sexy = sexy # Parents.__init__(self, name) super(Son2, self).__init__(name, *args, **kwargs) print('Son2------------>End') class GrandSon(Son1,Son2): def __init__(self, name, sexy, age): print('Grandson---------->Begin') # Son1.__init__(self, age, name) # Son2.__init__(self, sexy, name) super(GrandSon, self).__init__(age, sexy, name) print('Grandson---------->End') if __name__ == '__main__': print(GrandSon.__mro__) gs = GrandSon('李华', '男', 18) print('姓名:', gs.name) print('性别:', gs.sexy) print('年龄', gs.age)输出:
(<class '__main__.GrandSon'>, <class '__main__.Son1'>, <class '__main__.Son2'>, <class '__main__.Parents'>, <class 'object'>) Grandson---------->Begin Son1------------>Begin Son2------------>Begin Parent-------------->Begin Parent-------------->End Son2------------>End Son1------------>End Grandson---------->End 姓名: 李华 性别: 男 年龄 18参数不确定存不存在,可以设置这个,* args元组,**kwargs字典
相当于把元组拆开*相当于把字典拆开 def a_function(a, b, *args, **kwargs): print(a, b) print(args) print(kwargs) a_function(1, 2, 1, 2, 3, 4, hbh='sad1', asdhjk='121') >>> >>>1 2 (1, 2, 3, 4) {'hbh': 'sad1', 'asdhjk': '121'}实例属性属于对象 类属性属于类 类属性在内存中只保存一份 实例属性在每个对象中都要保存一份
实例方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。
实例方法:由对象调用;至少一个self参数;执行实例方法时,自动将调用该方法的对象赋值给self; 类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类赋值给cls; 静态方法:由类调用;无默认参数;
类里,def外,类属性;是实例对象共有的属性 实例对象的,自己特有的,是实例属性
创建对象其实是两步:调用__new__ 创建对象,申请内存空间 调用__init__对对象初始化
实例方法 带self
类方法可以修改类属性,传出类对象,把self改为cls
静态方法,无默认参数,@staticmethod
重点,@property,把函数变成了属性,return一个值,在实例方法的基础上加上property装饰器变为属性,并且参数只有一个self,调用的时候方法不用加括号啦 就是为了方便使用,将方法变为属性调用 @在python里叫语法糖。
方法前加@property语法糖?,取得属性值;@方法名.setter 设置值;@方法名.deleter删除属性
属性名 = property(方法名) bar = property(get_bar,set_bar,del_bar,‘doc…’)
通过property属性更容易,简化流程
私有属性的get和set方法可以取修改私有属性的值,property可以来升级get和set方法
访问不了,是因为python解释器把其名字改为_类名__私有属性名 这叫名字重整。
任何实现了__enter__() 方法和 exit()就是上下文管理器 with 上下文管理器 as f 就把enter()返回的给f ,遇到异常自动调用exit方法 对于系统资源, 文件打开,socket,都是有限的,如果打开了,一定要关闭
或者导入contextlib库里的contextmanger模块,用contextmanager模块修饰方法。在yeid前的就是正常执行代码,yield之后的就是异常执行代码
#任何实现了 __enter__()和__exit__()的方法的对象都是上下文管理器 class File(object): def __init__(self, filname, mode): self.filename = filname self.mode = mode def __enter__(self): print('entering') self.f = open(self.filename, self.mode) return self.f def __exit__(self, *args): print('exit') self.f.close() with File('a.txt', 'w') as f: print('writing') f.write('hello world') ''' 这里实现了这个功能呢,上下文管理器只要有enter和exit的魔法方法就是上下文管理器 with就可以用上下文管理器,enter正常执行的代码返回的值给f 如果执行过程中发生异常,就执行exit里的代码 ''' #上下文管理器的推荐方式,导入contextlib库,通过yield将函数分为上下文两部分,上面一部分是正常执行的部分,下面是异常处理部分 from contextlib import contextmanager @contextmanager def file(file_name, mode): f = open(file_name, mode) yield f f.close() with file('a.txt','w') as f: f.write('hello world')在类里用就是如下的效果
from contextlib import contextmanager class File(object): def __init__(self, filname, mode): self.filename = filname self.mode = mode @contextmanager def file(self): print('entering') self.f = open(self.filename, self.mode) yield self.f print('closing') self.f.close() f = File('a.txt', 'w') with f.file() as f: print('writing') f.write('hello world')