内置方法
__str__
:
1.
如果不重写__str__ return
会打印出内存地址
2. print()
打印的时候, 会自动触发该函数的执行
如果重写了,会打印出你想要的
class Foo:
def __init__(self, name):
self.name=name
def __str__(self):
return '['+self.name+']'
f = Foo('nick')
# print(f.__str__())
# 相当于上面那句
print(f)
l = [1,2,3,4]
# 本质其实也是调用list的__str__方法
print(l)
__repr__
跟 __str__
类似,但它是在交互式命令下直接写变量名,会执行__repr__
(了解)
小结:
str函数或者print函数调用的是obj.__str__()
repr函数或者交互式解释器调用的是obj.repr__()
注意:
如果__str__
没有被定义, 那么就会使用__repr__
来代替输出
__str__和__repr__
方法的返回值都都必须是字符串
重要( __setattr__ , __delattr__, __getattr__
: 对象加 (.)点 就会触发)
__getattr__
: 如果去对象中取属性,一但取不到,会进入__getattr__
; 对象加 (.) 赋值或修改值会触发
__setattr__
: 如果去对象中赋值属性,一但取不到,会进入__setattr__
; 对象加 (.) 获取值, 如果取不到, 会触发
__delattr__
: 如果删除对象中的属性, 会进入__delattr__
# 点拦截方法
class Foo:
def __init__(self, name):
self.name = name
def __getattr__(self, item):
print('hhhh')
return '你沙雕啊,没有这个字段'
def __setattr__(self, key, value):
print('yyyy')
def __delattr__(self, item):
print('bbbb')
f = Foo('nick')
print(f.name)
print(f.age)
print(f.__dict__)
print(f.name)
f.sex='male'
def f.name
print(f.__dict__) # 会发现没删掉
字典继承例子
# 原来的字典使用方法
di = dict(name='hys', age=17)
print(di)
# 写一个类继承字典, 可以让他(.)取值, 也可以括号取值
class Mydict(dict):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def __getattr__(self, item):
print(item)
return self[item]
def __setattr__(self, key, value):
self[key] = value
di = Mydict(name='hys', age=16)
# 取值的两种方法
print(di['name'])
print(di.age)
# 赋值的两种方法
di.like='milk'
print(di.like)
di['sex']='male'
print(di.sex)
例子总结:虽然他本质上也是,但是在这里我就能控制这些过程
__item__
系列:对象通过[ ] 中括号取值,赋值, 删除值的时候,会调用
class Foo:
def __init__(self,name):
self.name=name
def __getitem__(self, item):
# 一般用这种反射的方式, 但实际这两个意思是一样的
name = getitem(self, item)
return name
# 一般不会用这种方式
return self.__dict__[item]
def __setitem__(self, key, value):
self.__dict__[key]=value
def __delitem__(self, key):
print('del obj[key]时,我执行')
self.__dict__.pop(key)
f1=Foo('sb')
# 当我取值的时候, 会触发__getitem__方法
f1['age']=18
# 当我赋值时,会触发__setitem__方法
f1.age1=19
# 当我删除值的时候,会触发__delitem__方法
del f1.age1
del f1['age']
f1['name']='alex'
print(f1.__dict__)
__call__
对象加括号 或 类加括号会调用它
class Foo:
def __call__(self):
print('xxxxx')
f = Foo()
f()
__ enter__和__exit__
# 上下文管理器, 本质原理; with 顶头写会自动调用__exit__方法
with open() as f:
pass
递归问题
class Foo():
def __init__(self, name):
self.name = name
def __setattr__(self, key, value):
print('xxxx')
# 这种方法有问题! 会到达递归的最大深度
setattr(self, key, value)
def __getattr__(self, item):
return '没有值' # 因为是取不到才跳到这里, 所以再写个反射还是取不到
f = Foo('nick')
标签:__,反射,内置,name,self,item,print,方法,def
From: https://www.cnblogs.com/hanyingshuo/p/17797415.html