Day 27 面向对象补充
isinstance(obj,cls) 判断一个对象obj是否是一个类cls的实例化而来
issubclass(sub,super)判断类sub是否是类super的子类
__getattr__不存在的属性访问,触发__getattr__
__getattribute__不管是否存在属性都会触发__getattribute__
__setitem__ , __delitem__ , __getitem__ ,通过中括号[ ]字典的方式触发例del f1[‘name’]
__setattr__ ,delattr__, __getattr__, 通过点 . 的方式触发 例如del f1.name
###__str__ , __repr__都是控制输出的,输出return值,只能return字符串,不能return非字符串
class Foo:
def __str__(self):
return “自定制1” #可以控制打印信息
f1= Foo()
print(f1) #本质是str(f1),实际调用的f1.__str__()
>>> 自定制1
class Foo:
def __init__(self,name,age)
self.name=name
self.age=age
def __repr__(self):
return “名字是%s 年龄是%s” %(self.name,self.age) #__repr__在解释器中触发
f1= Foo(‘egon’,19) #触发__repr__
print(f1)
>>>名字是egon 年龄是19
#当__str__ , __repr__共存时print优先调用__str__,若找不到__str__再调__repr__
###format自定制格式化方法
#####一
x=’{0}:{0}-{0}’.format(‘dog’) #数字表示对应format里的字符串位置
print(x)
>>>dog:dog-dog
#####二
class Date:
def __init__(self,year,mon,day):
self.year=year
self.mon=mon
self.day=day
d1=Date(2016,9,27)
x="{0.year}{0.mon}{0.day}".format(d1)
y='{0.year}:{0.mon}:{0.day}'.format(d1)
z='{0.mon}-{0.day}-{0.year}'.format(d1)
print(x)
print(y)
print(z)
>>>
20161226
2016:12:26
12-26-2016
#####补充说明
if not 0:
print("ok")
>>>ok
if not 1:
print("ok")
>>>
#####三
format_dic={
'ymd':'{0.year}{0.mon}{0.day}',
'm-d-y':'{0.mon}-{0.day}-{0.year}',
'y:m:d':'{0.year}:{0.mon}:{0.day}'
}
class Date:
def __init__(self,year,mon,day):
self.year=year
self.mon=mon
self.day=day
def __format__(self, format_spec):
print('我执行啦')
print('--->',format_spec)
if not format_spec: #该if not判断为#当format_spec不存在时
format_spec='ymd' #当format_spec不存在时,此处设默认值
fm=format_dic[format_spec]
return fm.format(self)
d1=Date(2016,12,26)
format(d1) #调用d1.__format__
print(format(d1))
>>>
我执行啦 #执行format(d1)
--->
我执行啦 #执行print(format(d1))
--->
20161226
#####四、当format_spec不在字典的key值里时添加or format_spec not in format_dic:
def __format__(self, format_spec):
print('我执行啦')
print('--->',format_spec)
if not format_spec or format_spec not in format_dic:
format_spec='ymd'
fm=format_dic[format_spec]
return fm.format(self)
d1=Date(2016,12,26)
print(format(d1,'y:m:d'))
print(format(d1,"ajkdla"))
>>>
我执行啦 #执行print(format(d1,'y:m:d'))
---> y:m:d
2016:12:26
我执行啦 #执行print(format(d1,"ajkdla”)),即当format_spec不在字典的key值里时
---> ajkdla
20161226
########__slots__:为了省内存使用,附加限制了属性定义,即只能使用__slots__中定制好的key去赋值
__slots__:,,,,()
为何使用__slots__:字典会占用大量内存,如果你有一个属性很少的类,但是有很多实例,为了节省内存可以使用__slots__取代实例的__dict__
class Foo:
__slots__ = ['name','age']
def xyy(self):
pass
f1=Foo()
f1.name='xyy'
f1.age=18
###__doc__该属性无法继承,不定义自动赋值None
class Foo:
"我是沉迷于学习的美少女"
pass
f1=Foo()
print(f1.__doc__)
>>>我是沉迷于学习的美少女
###__class__ , __module__查看属性所属的类名和模块名
###__del__ 用del删除属性时会触发__del__的运行
###__call__对象后面加括号,触发__call__执行。
class Foo:
def __call__(self):
print("我运行了")
f1=Foo()
f1() #调用Foo下的__call__
Foo() #调用的是***下的__call__ ,因为一切皆对象
###迭代器协议:把对象变成可迭代对象的方法,在类中加__iter__,且调用__next__返回值
class Foo:
def __init__(self,n):
self.n=n
def __iter__(self):
return self
def __next__(self):
if self.n == 15:
raise StopIteration("n最大15")
self.n+=1
return self.n
f1=Foo(10)
print(f1.__next__()) #f1()即对象加括号且Foo类里有__iter__()即可成为迭代器,用__next__返回值
print(next(f1))
for i in f1: #for循环遵循迭代器协议即obj=iter(f1),f1.__iter__()
print(i) #相当于调用__next__()
####变量值赋值
a=2
b=1
c,d=b,a #即b赋值给c,a赋值给d
print(c,d)
>>>1 2
###用迭代器输出费波纳茨数列
class Foo:
def __init__(self,x=0,y=1):
self.x=x
self.y=y
def __iter__(self):
return self
def __next__(self):
self.x,self.y=self.y,self.x+self.y
if self.y>=100:
raise StopIteration("100内的费波纳茨数列")
return self.y
f1=Foo()
for i in f1:
print(i)