魔法方法

魔法方法

__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
posted @   ssrheart  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示