Python魔法方法

Python的魔法方法是特殊的方法,用于定义类的行为。它们以双下划线开头和结尾,例如__init____str__。魔法方法使对象行为变得更加直观和灵活。以下是一些常见的魔法方法:

1. __init__(self, ...)

初始化方法,在实例创建时自动调用,用于初始化对象的状态。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

obj = MyClass(10)
print(obj.value)  # 10

2. __new__(cls, ...)

构造方法,在创建实例之前调用,用于控制实例的创建过程。它负责返回一个新实例,是实例化对象的第一步。
__new____init__的区别:
__new__

  • 调用时机:__new__在创建对象之前被调用,是实例化对象的第一步。
  • 作用:负责返回一个新的实例。它是一个静态方法,通常用于自定义对象的创建过程,特别是在继承不可变类型(如int、str、tuple)时。
  • 返回值:必须返回一个类的实例(通常是通过调用super().new(cls)来实现)。
  • 参数:接受类本身作为第一个参数(通常命名为cls),后续参数与__init__相同。

__init__

  • 调用时机:__init__在对象创建之后被调用,是实例化对象的第二步。
  • 作用:用于初始化对象的状态。它是一个实例方法,通常用于设置实例的属性或执行其他初始化操作。
  • 返回值:不返回任何值(即返回None)。
  • 参数:接受实例本身作为第一个参数(通常命名为self),后续参数用于初始化对象。

示例

class MyClass:
    def __new__(cls, value):
        print('创建MyClass实例')
        return super().__new__(cls)

    def __init__(self, value):
        print('初始化MyClass')
        self.value = value


obj = MyClass(10)
print(obj.value)  # 创建MyClass实例 初始化MyClass 10

在这个示例中,__new__方法首先调用了父类的__new__方法来创建一个新实例,然后初始化了实例的value属性。__init__方法随后被调用来进一步初始化对象的状态。

3. __del__(self)

在对象被删除时调用,用于清理资源。

示例

class MyClass:
    def __del__(self):
        print("清除资源中...")

obj = MyClass()
del obj  # 输出: 清除资源中...

4. __str__(self)

用于定义对象的字符串表示,print()函数调用时使用。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return f"传递的值为:{self.value}"


obj = MyClass(10)
print(obj)  # 传递的值为:10

5. __repr__(self)

用于定义对象的官方字符串表示,这个方法的主要目的是为调试和开发提供清晰且准确的信息。当你在控制台中直接打印对象时,或者使用repr()函数时,__repr__方法会被调用。

reprstr 的区别:

  • repr:提供对象的官方表示,目标是明确和准确,主要用于开发和调试。
  • str:提供对象的非正式表示,目标是友好和可读,主要用于最终用户,也就是说str返回的结果可读性强,repr返回的结果更加准确。

如果只定义了__repr__而没有定义__str__,那么当调用print()或str()时,Python也会使用__repr__的返回值。

示例

class MyClass:
    def __str__(self):
        return '__str__'

    def __repr__(self):
        return '__repr__'

a
a = MyClass()
print(a) # __str__
print(repr(a)) # __repr__
# 交互模式下,直接输入对象a,调用的是__repr__方法

6. __len__(self)

定义对象的长度,len()函数调用时使用。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __len__(self):
        return len(self.value)

obj = MyClass([1, 2, 3, 4])
print(len(obj))  # 4

7. __getitem__(self, key)

定义对象的索引访问行为。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __getitem__(self, index):
        return self.value[index]

obj = MyClass([1, 2, 3, 4])
print(obj[2])  # 3

8. __setitem__(self, key, value)

定义对象的索引赋值行为。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __setitem__(self, index, value):
        self.value[index] = value

obj = MyClass([1, 2, 3, 4])
obj[2] = 10
print(obj.value)  # [1, 2, 10, 4]

9. __delitem__(self, key)

定义对象的索引删除行为。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __delitem__(self, index):
        del self.value[index]

obj = MyClass([1, 2, 3, 4])
del obj[2]
print(obj.value)  # [1, 2, 4]

10. __iter__(self)

定义对象的迭代行为,for循环调用时使用。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __iter__(self):
        return iter(self.value)

obj = MyClass([1, 2, 3, 4])
for item in obj:
    print(item)  # 输出: 1 2 3 4

11. __contains__(self, item)

定义对象的成员检查行为,in操作符调用时使用。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __contains__(self, item):
        return item in self.value

obj = MyClass([1, 2, 3, 4])
print(3 in obj)  # True
print(5 in obj)  # False

12. __call__(self, ...)

使对象可以像函数一样被调用。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __call__(self, new_value):
        self.value = new_value

obj = MyClass(10)
print(obj.value)  # 10
obj(20)
print(obj.value)  # 20

13. __add__(self, other)

定义对象的加法行为,+操作符调用时使用。类似的魔法方法还有__sub__(减法)、__mul__(乘法)、__truediv__(除法)等。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __add__(self, other):
        return MyClass(self.value + other.value)

obj1 = MyClass(10)
obj2 = MyClass(20)
obj3 = obj1 + obj2
print(obj3.value)  # 30

14. __eq__(self, other)

定义对象的相等比较行为,==操作符调用时使用。类似的魔法方法还有__ne__(不等)、__lt__(小于)、__le__(小于等于)、__gt__(大于)、__ge__(大于等于)等。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __eq__(self, other):
        return self.value == other.value

obj1 = MyClass(10)
obj2 = MyClass(10)
obj3 = MyClass(20)
print(obj1 == obj2)  # True
print(obj1 == obj3)  # False

15. __enter____exit__

定义对象的上下文管理行为,支持with语句。

示例

class MyContext:
    def __enter__(self):
        print("进入上下文")
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        print("退出上下文")


with MyContext():
    print("上下文操作中")
'''
输出:
进入上下文
上下文操作中
退出上下文
'''

16. __getattr__(self, name)__setattr__(self, name, value)

定义对象的属性访问和赋值行为。需要注意的是,为了避免无限递归,需要直接操作实例的__dict__属性。

示例

class MyClass:
    def __getattr__(self, name):
        return f"你所访问的属性{name}不存在"

    def __setattr__(self, name, value):
        print(f"设置属性{name}{value}")
        self.__dict__[name] = value


a = MyClass()
print(a.name) # 你所访问的属性name不存在
a.name = "lee" # 设置属性name为lee
print(a.name) # lee

17. __delattr__(self, name)

定义对象的属性删除行为。

示例

class MyClass:
    def __delattr__(self, name):
        print(f"删除属性 {name}")
        super().__delattr__(name)

obj = MyClass()
obj.age = 18
del obj.age  # 删除属性 age

18. __dir__(self)

自定义对象的属性列表,dir()函数调用时使用。

示例

class MyClass:
    def __dir__(self):
        return ['a', 'b']

obj = MyClass()
print(dir(obj))  # ['a', 'b']

19. __format__(self, format_spec)

定义对象的格式化行为,format()函数和f-strings调用时使用。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __format__(self, __format_spec):
        if __format_spec == 'a':
            return f"*** {self.value} ***"
        return str(self.value)


obj = MyClass(18)
print(format(obj, 'a'))  # *** 18 ***
print(f"{obj:a}")  # *** 18 ***
print(f'{obj:b}') # 18

20. __hash__(self)

定义对象的哈希值,使对象可用作字典键或存储在集合中。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __hash__(self):
        return hash(self.value)


obj = MyClass('a')
print(hash(obj))  # 输出对象的哈希值 7582294177259239944

21. __bool__(self)

定义对象的布尔值转换行为,bool()函数和条件语句调用时使用。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __bool__(self):
        return bool(self.value)

obj1 = MyClass(0)
obj2 = MyClass(10)

print(bool(obj1))  # False
print(bool(obj2))  # True

22. __getattribute__(self, name)

自定义属性访问行为。这个方法在访问任何属性时都会被调用,甚至包括魔法方法和内置方法调用,因此需要小心避免无限递归。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __getattribute__(self, name):
        print(f"访问属性 {name}")
        return super().__getattribute__(name)


obj = MyClass(10)
print(obj.value)  # 访问属性 value  10

23. __missing__(self, key)

定义字典类的缺失键行为,适用于子类化的字典类型。

示例

class MyDict(dict):
    def __missing__(self, key):
        return f"{key} not found"

my_dict = MyDict(a=1, b=2)
print(my_dict['a'])  # 1
print(my_dict['c'])  # c not found

24. __index__(self)

定义对象在使用索引操作时的行为,例如在切片操作中使用对象。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __index__(self):
        return self.value

obj = MyClass(3)
my_list = [1,2,3,4,5]
print(my_list[obj])  # 4
print(my_list[1:obj])  # [2,3]

25. __round__(self, n)

定义对象的舍入行为,round()函数调用时使用。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __round__(self, n=None):
        return round(self.value, n)

obj = MyClass(5.678)
print(round(obj, 2))  # 5.68

26. __reversed__(self)

定义对象的反向迭代行为,reversed()函数调用时使用。

示例

class MyClass:
    def __init__(self, value):
        self.value = value

    def __reversed__(self):
        return reversed(self.value)

obj = MyClass([1, 2, 3, 4])
print(list(reversed(obj)))  # [4, 3, 2, 1]

27. __matmul__(self, other)

定义矩阵乘法行为,@操作符调用时使用。类似的魔法方法还有__imatmul__

示例

import numpy as np

class Matrix:
    def __init__(self, matrix):
        self.matrix = matrix

    def __matmul__(self, other):
        return Matrix(np.matmul(self.matrix, other.matrix))

    def __repr__(self):
        return str(self.matrix)

m1 = Matrix([[1, 2], [3, 4]])
m2 = Matrix([[5, 6], [7, 8]])
print(m1 @ m2)  # [[19 22] [43 50]]
  • 32
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值