__str__与__repr__
在用print()函数时是调用类的__str__方法进行输出,且__str__方法里必须return字符串
__repr__是在Python解释器里被调用,当__str__方法不存在时print()函数会调用__repr__方法
class Foo:
def __init__(self,name):
self.name=name
def __str__(self):
return '执行str,名字是%s'%self.name
def __repr__(self):
return '执行repr,名字是%s'%self.name
f=Foo('Alex')
#>>>f
#>>>执行repr,名字是Alex
#>>>repr(f)
#>>>执行repr,名字是Alex
#>>>print(f)
#>>>执行str,名字是Alex
#>>>str(f)
#>>>执行str,名字是Alex
#>>>f.__str__()
#>>>执行str,名字是Alex
可以尝试将__str__注释后再运行一下看看是什么结果?
__format__
'{}'.format('alex')其实就是调用类的__format__方法
class TimeData:
def __init__(self,year,mon,day):
self.year=year
self.mon=mon
self.day=day
def __format__(self,sep):
format_dic={'y-m-d':'{0.year}-{0.mon}-{0.day}',
'd:m:y':'{0.day}:{0.mon}:{0.year}',
'ymd':'{0.year}{0.mon}{0.day}'}
if not sep or sep not in format_dic:
return format_dic['ymd'].format(self)
else:
return format_dic[sep].format(self)
t=TimeData(2018,4,4)
format(t)
format(t,'ymd')
format(t,'d:m:y')
format(t,'y-m-d')
#201844
#201844
#4:4:2018
#2018-4-4
__slot__
当创建类的实例p时,同时也会创建实例的字典p.__dict__
当类的属性不多且要创建很多实例时,这样会非常占用内存,于是便有了__slot__类属性
__slot__是类属性变量,它可以是列表,元组,可迭代对象,也可以是一个字符串(此时实例只能有这个字符串对应的一个属性名),它规定了实例的属性名只能在__slot__的范围内取,当创建不在__slot__内的属性时会报错,可以用它来限制实例的属性.
当__slot__存在时就不会创建实例的字典,即p.__dict__不存在,实例p没有__dict__属性,解决了内存占用问题
class Foo:
__slots__ = ['name','age']
f=Foo()
#print(f.__dict__)#报错 'Foo' object has no attribute '__dict__'
f.name='alex'
print(f.name)
f.age=18
print(f.age)
#f.gender='male'#报错'Foo' object has no attribute 'gender',因为__slot__里没有gender这个属性名
__doc__
返回类的文本描述,子类不会继承.当没有文本时返回None
class Foo:
'''this is Foo'''
__slots__ = ['name','age']
class Bar(Foo):
pass
print(Foo.__doc__)
print(Bar.__doc__)
#this is Foo
#None
__call__
对象后面加括号,触发执行。
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
相当于把对象直接变成一个方法
class Foo:
def __call__(self, *args, **kwargs):
return args
f=Foo()
print(f(1,2,3,4,5))
#(1, 2, 3, 4, 5)
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么
__iter__与__next__
__iter__把对象变成迭代器然后用__next__获取值
class Range():
'''模拟range函数'''
def __init__(self,start,end,step=1):
self.n=start
self.end=end
self.step=step
def __iter__(self):
return self
def __next__(self):
if self.n>=self.end:
raise StopIteration
x=self.n
self.n+=self.step
return x
for i in Range(0,5):
print(i)
斐波那契数列
class Fib:
def __init__(self,n):
self.n=n
self._a=0
self._b=1
self.count=1
def __iter__(self):
return self
def __next__(self):
if self.count>self.n:
raise StopIteration
self._a,self._b=self._a+self._b,self._a
self.count+=1
return self._a
for i in Fib(8):
print(i)