一、__new__;__init__
定义:
__init__(self[, ...]):构造器,当一个实例被创建的时候调用的初始化方法
__new__(cls[, ...]): 是在一个对象实例化的时候所调用的第一个方法
eg:
class Test(object):
def __init__(self, a, b, c):
# 对‘对象‘做初始化的,__new__对象创建之后执行的
print('-------init------方法')
def __new__(cls, *args, **kwargs):
print('------new方法-------')
obj = super().__new__(cls)
return obj
t = Test(11, 22, 33)
print(t)
eg2---单例模式:
class TestDemo:
# 保存创建对象的属性,要定义为私有属性
__instance = 0
def __new__(cls, *args, **kwargs):
# 判断类是否创建过对象
if cls.__instance == 0:
# 没有就创建一个,保存为__instance
cls.__instance = super().__new__(cls)
# 返回创建好的对象
return cls.__instance
二、__enter__;__exit__
定义:
__enter__(self):
- 定义当使用 with 语句时的初始化行为
- __enter__ 的返回值被 with 语句的目标或者 as 后的名字绑定
__exit__(self, exc_type, exc_value, traceback):
- 定义当一个代码块被执行或者终止后上下文管理器应该做什么
- 一般被用来处理异常,清除工作或者做一些代码块执行完毕之后的日常工作
eg:
from requests.sessions import Session
with Session() as s:
s.get('http://www.baidu.com')
class MyOpen:
def __init__(self, filename, mode, encoding='utf-8'):
self.f = open(filename, mode=mode, encoding=encoding)
def __enter__(self):
print('---enter---')
return self.f
def __exit__(self, exc_type, exc_val, exc_tb):
print('-----exit---')
print(exc_type,exc_val,exc_tb)
self.f.close()
with MyOpen('eee.txt', 'w', encoding='utf-8') as f:
f.write('222288888888888')
三、__call__
__call__(self[, args...]):允许一个类的实例像函数一样被调用:x(a, b) 调用 x.__call__(a, b)
# 函数是一个可调用的对象
def work():
print('----work---')
class Demo:
def __call__(self, *args, **kwargs):
print('----call----')
d = Demo()
print(d)
print(work)
# ==============callable:判断对象是否可调用=============
print(callable(d))
print(callable(work))
# 可调用的对象,加() 就会执行对象的__call__方法。
# d() # d.__call__(d)
四、 __str__
__str__(self):定义当被 str() 调用时的行为
class Demo:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
"""对象被输出到控制台时,显示的内容由该方法决定
该方法返回值必须是一个字符串
"""
return self.name
五、__repr__
_repr__(self):定义当被 repr() 调用时的行为
class Demo2:
def __str__(self):
return '1111'
def __repr__(self):
"""返回对象的原始信息"""
return '字符串121212'
六、算术运算符对应的魔术方法:
__add__(self, other):定义加法的行为:+
__sub__(self, other):定义减法的行为:-
__mul__(self, other):定义乘法的行为:*
__truediv__(self, other):定义真除法的行为:/
__floordiv__(self, other):定义整数除法的行为://
__mod__(self, other):定义取模算法的行为:%
# 对象相加触发的魔术方法是:__add__
# 对象相减触发的魔术方法是:__sub__
class Test(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __add__(self, other):
"""返回两个对象的age之和"""
print('对象之间使用了+号')
return self.age + other.age
def __sub__(self, other):
return self.replace(other, '')
七、属性自省:
私有属性:Python并没有真正的私有化支持,但可用下划线得到伪私有,有一项大多数 Python 代码都遵循的习惯:带有下划线,前缀的名称应被视为非公开的 API 的一部分(无论是函数、 方法还是数据成员)。
"""
1、私有的属性和方法为双下滑先开头的
2、在类里面不管是私有的属性,还是方法,都只能在类里面使用
3、私有的属性和方法是不能继承
# 对象的__dict__属性:返回的是对象的属性字典
"""
class Demo3:
attr = 100
# 类的私有属性
_attr = 900 # 声明式的私有属性(程序员之间默认的私有属性)
__attr2 = 200 # 真正的私有属性
def __init__(self):
# 对象的私有属性
self.__name = 'demo3'
self.name = 'demo3333'
@classmethod
def work(cls):
# 获取私有的类属性
print(cls.__attr2)
# 调用私有的类方法
cls.__work2()
print('----work----')
# 类私有的方法
@classmethod
def __work2(cls):
print("---work2------")
def work4(self):
# 在类里面获取私有实例属性
print(self.__name)
# 调用私有的实例方法
self.__work5()
print('----work4-----')
# 对象的私有方法(私有的实例方法)
def __work5(self):
print('-------work5-----')
print(Demo3.__dict__)
class A(Demo3):
def work1(self):
pass
# 私有的属性和方法是不能继承
# print(self.__attr)
# print(self.__name)
# self.__work2()
# self.__work5()
a = A()
a.work1()
八、__dict__
- 类调用 __dict__ 属性,返s类属性和方法的字典。
- 实列调用 __dict__ 属性,返回的值实列相关的实例属性
九、__slot__
"""
__slots__的两个作用:
1、限制实例对象的属性
2、阻止属性字典的创建(对象不会拥有__dict__)
"""
# 给自定义的类添加属性限制
class Demo:
# 通过__slots__属性可以限制类的实例 的属性
#
__slots__ = ['name', 'age']
# __slots__ = []
def work(self):
print("---work----")
d = Demo()
d.work()
d.name = 99
print(d.name)
十、__getattr__,__setattr__,__delattr__,__getattribute__
class Demo(object):
def __init__(self, name, age):
"""
:param name: str类型
:param age: int类型
"""
self.name = name
self.age = age
def __setattr__(self, key, value):
"""在__setattr__方法中可以对属性的创建过程做干预"""
# 属性设置的魔术方法
if key == 'name':
if isinstance(value, str):
# 调用父类的__setattr__方法设置属性
super().__setattr__(key, value)
else:
raise TypeError('name属性的值必须为字符串')
elif key == 'age':
if isinstance(value, int):
# 调用父类的__setattr__方法设置属性
super().__setattr__(key, value)
else:
raise TypeError('age属性的值必须为int类型')
else:
super().__setattr__(key, value)
# print("属性{},值为{}".format(key, value))
def __delattr__(self, item):
"""删除属性的方法"""
if item == 'name':
raise AttributeError('name属性不支持删除')
else:
# 调用父类的属性进行删除操作
super().__delattr__(item)
def __getattribute__(self, item):
"""获取属性的方法"""
print("获取的属性名为:", item)
# 调用父类的方法去获取属性
try:
value = super().__getattribute__(item)
except AttributeError:
value = None
return value
def __getattr__(self, item):
"""获取的属性不存在时,触发的方法"""
# print('item:', item)
pass
dd = Demo('xiaoming', 999)
# ============属性设置==============
# dd.sex = '男'
# print(dd.__dict__)
# =========删除对象的属性=============
# del dd.name
# del dd.age
# delattr(dd, 'sex')
# print(dd.__dict__)
# =========属性获取的魔术方法==============
# print(dd.age1)
# 判断属性是否存在
# hasattr(dd, 'age')
附录:https://www.cnblogs.com/nmb-musen/p/10861536.html