魔法方法
魔法方法
__init__ :初始化类时触发
__del__ :删除类时触发
__new__ :构造类时触发
__str__ :str函数或者print函数触发
__repr__ :repr或者交互式解释器触发
__doc__ :打印类内的注释内容
__enter__ :打开文档触发
__exit__ :关闭文档触发
__getattr__ : 访问不存在的属性时调用
__setattr__ :设置实例对象的一个新的属性时调用
__delattr__ :删除一个实例对象的属性时调用
__setitem__ :列表添加值
__getitem__ :将对象当作list使用
__delitem__ :列表删除值
__call__ :对象后面加括号,触发执行
(1)__init__
__init__(self, ...): 初始化方法,创建对象时自动调用。
class MyClass:
def __init__(self, name):
self.name = name
obj = MyClass(name='heart')
print(obj.name) # heart
(2)__del__
__del__(self): 删除类时触发。
class MyClass:
def __del__(self):
print("对象正在被删除")
obj = MyClass()
del obj # 这会触发 __del__
# 输出:对象正在被删除
(3)__new__
__new__(cls, ...)__new__是 Python 类中的特殊方法,它用于创建一个新的实例。与__init__不同,__new__是在实例被创建之前调用的,而__init__是在实例已经被创建之后调用的,用于初始化实例的属性。
class MyClass:
def __new__(cls, *args, **kwargs):
# 自定义创建实例的逻辑
instance = super().__new__(cls)
print("Creating a new instance")
return instance
def __init__(self, name):
# 初始化实例的属性
self.name = name
# 使用 __new__ 创建实例
obj = MyClass(name="example")
print(obj.name) # example
(4)__str__
__str__(self): 在打印对象的时候触发,返回值必须是字符串- 用处:就是用来定制打印对象显示返回信息的
class MyClass:
def __init__(self, name):
self.name = name
def __str__(self):
return f"当前是{self.name}"
obj = MyClass(name='heart')
print(obj) # 输出:当前是heart
(5)__repr__
__repr__(self): repr 或者交互式解释器触发。
class MyClass:
def __init__(self, name):
self.name = name
def __repr__(self):
return f"MyClass({self.name})"
obj = MyClass(name='heart')
print(repr(obj)) # 输出:MyClass(heart)
(6)__doc__
__doc__: 打印类内的注释内容。
class MyClass:
"""这是一个示例类"""
def __init__(self, name):
self.name = name
print(MyClass.__doc__) # 输出:这是一个示例类
(7)__enter__
__enter__(self): 打开文档触发,通常与with语句一起使用。
class MyContext:
def __enter__(self):
print("打开文档")
return self
def __exit__(self, exc_type, exc_value, traceback):
print("关闭文档")
def save(self):
print("保存成功")
with MyContext() as context:
# 在这里执行一些操作
context.save() # 保存成功
# 这将触发 __exit__
(8)__exit__
__exit__(self, exc_type, exc_value, traceback): 关闭文档触发,通常与with语句一起使用。
class MyContext:
def __enter__(self):
print("打开文档")
return self
def __exit__(self, exc_type, exc_value, traceback):
print("关闭文档")
def save(self):
print("保存成功")
with MyContext() as context:
# 在这里执行一些操作
context.save() # 保存成功
# 这将触发 __exit__
(9)__getattr__
__getattr__(self, item): 访问不存在的属性时调用。
class MyClass:
def __getattr__(self, item):
return f"属性 {item} 不存在"
obj = MyClass()
print(obj.age) # 输出:属性 age 不存在
(10)__setattr__
__setattr__(self, key, value): 设置实例对象的一个新的属性时调用。
class MyClass:
def __setattr__(self, name, value):
print(f"设置属性 {name} 为 {value}")
obj = MyClass()
obj.age = 18 # 输出:设置属性 age 为 18
(11)__delattr__
__delattr__(self, item): 删除一个实例对象的属性时调用。- 在这里要注意,实际上要加super().属性方法才会执行相应操作
class MyClass(object):
def __init__(self):
self.age = 19
def __delattr__(self, item):
print(f"删除属性 {item}")
super().__delattr__(item)
obj = MyClass()
print(hasattr(obj, 'age')) # True
del obj.age # 输出:删除属性 age
print(hasattr(obj, 'age')) # False
(12)__setitem__
__setitem__(self, key, value): 列表添加值。
class MyList:
def __init__(self):
self.items = []
def __setitem__(self, key, value):
print(f"在索引 {key} 处设置值 {value}")
self.items[key] = value
my_list = MyList()
my_list[0] = 10 # 输出:在索引 0 处设置值 10
(13)__getitem__
__getitem__(self, key): 将对象当作 list 使用。
class MyList:
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return self.items[index]
my_list = MyList([1, 2, 3, 4])
print(my_list[2]) # 输出:3
(14)__delitem__
__delitem__(self, key): 列表删除值。
class MyList:
def __init__(self, items):
self.items = items
def __delitem__(self, index):
print(f"删除索引 {index} 的值")
del self.items[index]
my_list = MyList([1, 2, 3, 4])
del my_list[1] # 输出:删除索引 1 的值
(14)__call__
__call__(self, ...): 对象后面加括号,触发执行。
class Math():
def __call__(self, x, y):
print(x + y)
add_func = Math()
add_func(x=10, y=20) # 30
(15)__getattribute__
-
object.__getattribute__(self, name):当试图访问对象的属性时,方法会被调用。 -
如果类里面定义了这个方法,在获取属性不存在的属性会先触发,
__getattribute__,再触发__getattr__。 -
该方法返回对象的属性值。通常,不需要直接调用
__getattribute__,而是在类中进行重写以自定义对象的属性获取行为。
class Heart:
def __init__(self,name):
self.name = name
def __getattribute__(self, item):
print(f"当前是{item}")
# 使用 super().__getattribute__ 来获取属性值,避免无限递归
return super().__getattribute__(item)
# 创建对象
heart = Heart(name='heart')
print(heart.name)
-
在上述例子中,当访问
heart.name时,__getattribute__方法会被调用,并打印出 "当前是name"。在这里,我们使用了super().__getattribute__(name)来获取实际的属性值。 -
需要注意的是,如果在
__getattribute__方法中直接访问同一属性,可能会导致无限递归,因此要确保使用super().__getattribute__或者避免直接在该方法中访问相同的属性。
继承dict并重写
class Heart(dict):
def __getattr__(self, item):
print(f'已获取!')
return self.get(item)
def __setattr__(self, key, value):
print(f'已设置!')
self[key] = value
heart = Heart()
heart.name = 'heart' # 已设置!
print(heart.name) # 已获取! heart

浙公网安备 33010602011771号