调用不存在的属性sex会报错(报错后不会再读下面的代码)
第一个参数是实例化出来的对象,第二个参数必须要是字符串类型的,字符串里面的字符是类里面的属性
hasattr查看有没有这个属性
getattr方法获取对象lili里面name的属性值,有就可以得到,没有也会报错
setattr
给对象添加上一种属性和属性值
delattr 属性调用过程dir(对象)查看对象里面的所有成员,查看属性,查看方法
object (超类或基类):我们所有自己定义的类,都会继承object这个类里面的方法。是所有类的父类对象.__getattribute__('属性'):也是获取属性值的
有两个下划线的是方法
属性的调用过程
有一个实例对象lili
lili.sex(获取莉莉对象的sex属性)
1、判断是否存在sex属性
有:调用__getattribute__('属性')(内部自己完成) 获取对象的指定属性值
没有:调用__getattr__(对象调用属性时作出提示)将要操作的属性传进该方法
如果没有定义__getattr__ object类没有 自己的类也没有定义,就会报错
有定义就不会报错,所以需要自己写一个__getattr__方法 对象关系方法
所有的数据类型本质都是一个类
str 类 字符串类
int 类 整形类
'abc' 对象 是字符串类的对象
1 对象 是整形类的对象
>>> issubclass(Person,object)#判断第一个类型时不是后面类的子类
True
>>> isinstance(lili,Person)#判断对象(前面)是否是该类(后面)的实例化对象
True
>>> isinstance(1,int)
True
>>> type(1)==int
True
>>> type(lili)==Person
True
#type只能进行一种类型的判断,如果要进行多种的话就需要用逻辑运算符(or)
#isinstance能够进行多种类型的判断(加逗号),中间的逗号是or不能做and
#type类型会更严谨一些,是不会兼容父类的,即使它继承了父类,它只看,你是不是它本身那个类,不会去管它本身那个类继承了谁。因为type是得到这个数据是什么类型的,是不会判断他是否继承了哪些父类的,
#isinstance是包含父类的,只要它继承了父类,他就可以是父类的实例化对象
>>> type(lili)==object
False
>>> isinstance(lili,object)
True
__init__方法是在我们创建实例化对象的时候(即把对象初始化的时候),就会去调用了
__del__析构函数是在我们用del关键字时,就自己执行了
外观:两个下划线开头 两个下划线结尾 中间是单词
作用:魔法方法神奇的地方在于不需要自己调用,会在某种特定的场景自动执行,是由Python解释器执行
魔法方法只需要定义,自动在符合规则的场景下自动调用
class Earth:
def __new__(cls):
print('new',cls)
return super().__new__(cls)
def __init__(self):
print('init')
e=Earth()
Earth()创建对象(在没有定义__new__时)的正确步骤:
1。调用object类的__new__方法创建指定类的对象
2.对该对象进行初始化,调用_init__方法
先给new创建,然后把创建好的给init初始化
__new__什么时候被调用(初始化之前调用):实例化自动调用 是第一个被调用的方法,在初始化执行会影响初始化(出厂设置),阻拦了init执行
实例化其实是由new完成的,而不是init
作用:创建对象是由__new__方法执行的,是用来创建对象的
重写new就不会再创建对象
不管顺序怎么放都会先执行new方法
单例模式cls就是Earth本身
super().__new__()调用了父类的方法创建对象
单例模式,就像回收站,只能打开一个窗口,无论点击多少次都只能打开一个窗口
不管创建多少个都是一样的,都是一个对象,只是名字不一样
变量保存的是地址值
修改一个对象,类的其他实例对象也会进行修改
单例模式,本来我只想创建一个对象,但别人用我的方法时·,别人不知道,别人想创建多个,但是我固定,我写死了,只能创建一个
对象加括号就会调用call魔法方法
自定义的对象不可以通过下标取取值,说明自定义的对象不是序列类型
协议的本质是魔法方法可以用序列协议把自定义对象转化为序列类型
主要通过getitem和len来确定是不是序列类型
先使外观看起来像列表
所以定义一个元组不定长
用for循环获取不定长的内容
但因为其还没有下标,只是有值而已,所以还不能通过下标取值
怎么拿到下标?需要用到枚举法
相当于自己定义的类已经是序列类型了
想要输出的不是地址值 ,重写一下repr方法
重点是 len和getitem
序列器协议即可以通过迭代,把数据一一便利出来,使得自己定义的类 和range ()函数的功能一样
next()是内置函数,可以依次获取到里面的元素
迭代器用到的是iter(使其变为可迭代对象)和next这两个方法,
列表和元组等都只是可迭代对象,不是迭代器 ,需要通过iter内置函数转成迭代器
迭代器可以通过next内置函数依次获取到里面的内容
自己写一个迭代器就需要用到iter和next方法
变成迭代器之后还能通过next()方法一个个进行取值
上下文协议打开文件后自动执行下面的读取和写入
想要让自己的类变成自动执行
用with关键字自动打开自己定义的类,然后去执行这个类,然后结束这个类,会自动去调用还会自动清理释放代码块中所占用的资源



