一、__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__

object.__getattr__
当属性查找在通常的地方没有找到该属性时调用
object.__getattribute__
查找属性时,第一时间会调用该方法
object.__setattr__
设置属性时,调用该方法设置属性,
object.__delattr__
在del obj.attr删除属性时触发
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