python中的魔法函数


魔法函数有哪些

1.什么是魔法函数?

  • 魔法函数是Python中定义的,以__开头,结尾,形如__fun()的函数,一般使用已经定义好了的即可。
  • 使用这样一些函数,可以让我们自定义的类有更加强大的特性。
  • 魔法函数一般是隐式调用的,不需要我们显示调用。(即python解释器帮我们调用实现)

2.魔法函数的特点

  • 以双下划线开头和结尾(如__init__)
  • 由Python解释器自动调用,通常不直接调用
  • 为类提供特殊功能,使其行为更像内置类型

魔法函数的优缺点
优点:
增强代码的可读性和可维护性。
提高代码的灵活性和功能。
与Python语言深度集成。

缺点:
滥用可能导致代码复杂性和难以理解。
可能引入性能开销,特别是在频繁调用时。
不当使用可能导致调试困难。

3.魔法函数有什么作用?

  • 实现特殊操作:用于对象的初始化(init)、销毁(del)、属性访问(getattrsetattrdelattr)等。
  • 运算符重载:允许自定义类重载标准运算符,如加法(add)、减法(sub)、乘法(mul)等,使对象可以像内置类型一样参与运算。
  • 支持内置函数和协议:通过实现特定方法,如__len__、iter、__getitem__等,使自定义对象支持内置函数(如len()、iter())和协议(如迭代协议)。
  • 增强可读性和可维护性:利用运算符重载和内置协议,使代码更简洁易懂。
  • 提高代码灵活性:允许定义对象的复杂行为,增强自定义类的表现力和灵活性。
  • 与Python语言深度集成:利用Python的动态特性,使自定义对象无缝融入Python生态系统。

常见的魔法函数

  • init(self,…):构造函数,在创建对象时自动调用,用于初始化对象的属性。
  • str(self):返回对象的字符串表示,用于print()函数或str()转换。
  • repr(self):返回对象的官方字符串表示,通常用于调试,由repr()函数调用。
  • len(self):定义对象的长度,用于len()函数。
  • getitem(self, key):允许对象使用索引操作,如obj[key]。
  • setitem(self, key, value):允许对象使用索引赋值,如obj[key] = value。
  • eq(self, other):定义等号(==)的行为,用于比较两个对象是否相等。
  • add(self, other):定义加号(+)的行为,用于对象的加法运算。
  • iter(self) 和 next(self):使对象成为迭代器,分别返回迭代器本身和序列的下一个元素。
  • call(self,…):使实例能够像函数一样被调用。

魔法函数可以为你写的类增加一些额外功能,方便使用者理解。举个简单的例子,我们定义一个“人”的类People,当中有属性姓名name、年龄age。让你需要利用sorted函数对一个People的数组进行排序,排序规则是按照name和age同时排序,即name不同时比较name,相同时比较age。由于People类本身不具有比较功能,所以需要自定义,你可以这么定义People类:

class People(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        return

    def __str__(self):
        return self.name + ":" + str(self.age)

    def __lt__(self, other):
        return self.name < other.name if self.name != other.name else self.age < other.age


if __name__=="__main__":

    print("\t".join([str(item) for item in sorted([People("abc", 18),
        People("abe", 19), People("abe", 12), People("abc", 17)])]))

4.常见魔法函数

1.init(self[, args…]):对象初始化函数,在创建对象时调用。

class MyClass:
    def __init__(self, name):
        self.name = name
obj = MyClass("Alice")

2.str(self):返回对象的字符串表示。

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __str__(self):
        return f"({self.x}, {self.y})"
p = Point(3, 4)
print(p)  # 输出: (3, 4)

3.len(self):返回对象的长度。

class MyList:
    def __init__(self, items):
        self.items = items
    def __len__(self):
        return len(self.items)
my_list = MyList([1, 2, 3, 4, 5])
print(len(my_list))  # 输出: 5

4.getitem(self, key):获取对象的指定元素。

class MyList:
    def __init__(self, items):
        self.items = items
    def __getitem__(self, index):
        return self.items[index]
my_list = MyList([1, 2, 3, 4, 5])
print(my_list[2])  # 输出: 3

5.setitem(self, key, value):设置对象的指定元素。

class MyList:
    def __init__(self, items):
        self.items = items
    def __setitem__(self, index, value):
        self.items[index] = value
my_list = MyList([1, 2, 3, 4, 5])
my_list[2] = 10
print(my_list.items)  # 输出: [1, 2, 10, 4, 5]

6.delitem(self, key):删除对象的指定元素。

class MyList:
    def __init__(self, items):
        self.items = items
    def __delitem__(self, index):
        del self.items[index]
my_list = MyList([1, 2, 3, 4, 5])
del my_list[2]
print(my_list.items)  # 输出: [1, 2, 4, 5]

7.contains(self, item):判断对象是否包含指定元素。

class MyList:
    def __init__(self, items):
        self.items = items
    def __contains__(self, item):
        return item in self.items
my_list = MyList([1, 2, 3, 4, 5])
print(3 in my_list)  # 输出: True

8.iter(self):返回迭代器对象。

class MyList:
    def __init__(self, items):
        self.items = items
    def __iter__(self):
        return iter(self.items)
my_list = MyList([1, 2, 3, 4, 5])
for item in my_list:
    print(item)  # 依次输出: 1, 2, 3, 4, 5

9.next(self):返回迭代器的下一个元素。

class MyList:
    def __init__(self, items):
        self.items = items
        self.index = 0
    def __iter__(self):
        return self
    def __next__(self):
        if self.index >= len(self.items):
            raise StopIteration
        value = self.items[self.index]
        self.index += 1
        return value
my_list = MyList([1, 2, 3, 4, 5])
for item in my_list:
    print(item)  # 依次输出: 1, 2, 3, 4, 5

10.eq(self, other):判断两个对象是否相等。

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
p1 = Point(3, 4)
p2 = Point(3, 4)
print(p1 == p2)  # 输出: True

11.lt(self, other):判断一个对象是否小于另一个对象。

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __lt__(self, other):
        return self.x < other.x and self.y < other.y
p1 = Point(2, 3)
p2 = Point(3, 4)
print(p1 < p2)  # 输出: True

12.gt(self, other):判断一个对象是否大于另一个对象。

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __gt__(self, other):
        return self.x > other.x and self.y > other.y
p1 = Point(3, 4)
p2 = Point(2, 3)
print(p1 > p2)  # 输出: True

13.add(self, other):定义对象的加法操作。

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)
v1 = Vector(1, 2)
v2 = Vector(3, 4)
result = v1 + v2
print(f"({result.x}, {result.y})")  # 输出: (4, 6)

14.sub(self, other):定义对象的减法操作。

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __sub__(self, other):
        return Vector(self.x - other.x, self.y - other.y)
v1 = Vector(3, 4)
v2 = Vector(1, 2)
result = v1 - v2
print(f"({result.x}, {result.y})")  # 输出: (2, 2)

15.mul(self, other):定义对象的乘法操作。

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __mul__(self, factor):
        return Point(self.x * factor, self.y * factor)
p = Point(2, 3)
result = p * 2
print(f"({result.x}, {result.y})")  # 输出: (4, 6)

16.call(self[, args…]):使对象可调用。

class Calculator:
    def __call__(self, a, b):
        return a + b
calc = Calculator()
result = calc(3, 4)
print(result)  # 输出: 7

17.enter(self) 和 exit(self, exc_type, exc_value, traceback):定义上下文管理器。

class FileManager:
    def __init__(self, filename):
        self.filename = filename
    def __enter__(self):
        self.file = open(self.filename, 'r')
        return self.file
    def __exit__(self, exc_type, exc_value, traceback):
        self.file.close()
with FileManager("example.txt") as file:
    contents = file.read()
    print(contents)

18.getattr(self, name):在访问不存在的属性时调用。

class Person:
    def __getattr__(self, name):
        return f"Attribute '{name}' does not exist."
p = Person()
print(p.age)  # 输出: Attribute 'age' does not exist.

19.setattr(self, name, value):在设置属性值时调用。

class Person:
    def __setattr__(self, name, value):
        print(f"Setting attribute '{name}' to '{value}'")
        super().__setattr__(name, value)
p = Person()
p.name = "Alice"  # 输出: Setting attribute 'name' to 'Alice'

20.delattr(self, name):在删除属性时调用。

class Person:
    def __delattr__(self, name):
        print(f"Deleting attribute '{name}'")
        super().__delattr__(name)
p = Person()
del p.name  # 输出: Deleting attribute 'name'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值