魔法方法

魔法方法

__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 @ 2024-01-08 15:42  ALPACINO6  阅读(26)  评论(0)    收藏  举报