Python的类内置方法,也称为魔术方法或特殊方法,允许开发者自定义类的行为,使得对象能够像内置类型一样操作。以下是一些常用的内置方法:
1-__init__(self, ...)
构造函数,在创建实例时自动调用,用于初始化实例属性。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
2-__new__(cls, ...)
实际上是创建实例对象的方法,通常在需要修改实例创建过程时使用,例如实现单例模式。
2-1-创建实例
class MyClass:
def __new__(cls, *args, **kwargs):
print("Creating instance")
# 调用父类(这里是 'object')的 __new__ 方法来创建实例
instance = super(MyClass, cls).__new__(cls)
return instance
def __init__(self, value):
print("Initializing instance")
self.value = value
# 创建 MyClass 的实例
obj = MyClass(10)
print(obj.value) # 输出: 10
2-2-单例模式
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
print("Creating new instance")
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
else:
print("Using existing instance")
return cls._instance
def __init__(self, value):
# 注意:由于只创建一次实例,因此 __init__ 每次都会被调用
# 需要小心处理初始化逻辑避免覆盖之前的值
self.value = value
# 测试单例模式
singleton1 = Singleton(10)
singleton2 = Singleton(20)
print(singleton1 == singleton2) # 输出: True,因为singleton1和singleton2指向同一个实例
print(singleton1.value) # 输出: 20,注意这里值被第二次调用 __init__ 时更新了
print(singleton2.value) # 输出: 20
3-__del__(self)
它定义了当一个对象即将被销毁时应该执行的操作。这个方法可以用于执行清理工作,比如关闭文件、释放资源等。需要注意的是,由于 Python 的LaJi回收机制依赖引用计数和循环LaJi收集器,__del__ 方法的调用时机并不是完全确定的,特别是在存在循环引用的情况下
import time
class FileHandler:
def __init__(self, filename):
print("Opening file")
self.file = open(filename, 'w') # 打开文件进行写入
def write(self, message):
self.file.write(message + '\n')
def __del__(self):
print("Closing file")
self.file.close() # 确保在对象销毁前关闭文件
# 创建 FileHandler 实例并写入一些数据
fh = FileHandler('example.txt')
fh.write("Hello, World!")
fh.write("This is a test.")
# 强制垃圾回收,这将触发 __del__ 方法
time.sleep(2) # 等待一段时间以确保所有操作完成
del fh # 显式删除实例,通常不需要这样做,这里为了演示效果
4-__str__(self)
定义了当使用`print()`函数或`str()`函数转换时对象应该如何表示。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person(name={self.name}, age={self.age})"
p = Person("Alice", 30)
print(p) # 使用了__str__方法输出更友好的字符串表示形式
输出结果
5-__repr__(self)
定义对象的“官方”字符串表示形式。它主要用于调试和开发过程中提供一个详细的、明确的对象表示。理想情况下,__repr__ 方法应该返回一个字符串,该字符串如果传给 eval() 函数可以重新创建这个对象(尽管在实践中这并不总是可行或实用的)。当没有定义 __str__ 方法时,Python 会使用 __repr__ 方法作为替代。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
# 返回一个字符串,理论上可以通过 eval() 重建对象
return f"Point({self.x}, {self.y})"
p = Point(1, 2)
print(p) # 输出: Point(1, 2)
print(repr(p)) # 输出: Point(1, 2),与 print(p) 相同,因为没有定义 __str__
6-__len__(self)
使对象支持`len()`函数,返回对象的长度。
class MyCollection:
def __init__(self, data):
self.data = data
def __len__(self):
return len(self.data)
coll = MyCollection([1, 2, 3])
print(len(coll)) # 使用了__len__方法
7-__getitem__(self, key)` 和 `__setitem__(self, key, value)
分别允许对象使用索引操作进行获取和设置值,如`obj[key]`。
class MyCollection:
def __init__(self, data):
self.data = data
def __getitem__(self, index):
return self.data[index]
def __setitem__(self, index, value):
self.data[index] = value
coll = MyCollection([1, 2, 3])
print(coll[0]) # 使用了__getitem__方法
coll[0] = 10 # 使用了__setitem__方法
print(coll[0])
8-__iter__(self)` 和 `__next__(self)
使对象成为可迭代对象。`__iter__`返回迭代器对象,该对象应该实现了`__next__`方法来提供下一个值。
class CountDown:
def __init__(self, start):
self.start = start
self.current = start
def __iter__(self):
return self
def __next__(self):
if self.current <= 0:
raise StopIteration
else:
self.current -= 1
return self.current + 1
for num in CountDown(5):
print(num)
输出结果
9-__contains__(self, item)
支持`in`关键字,检查对象是否包含某个元素。
class MySet:
def __init__(self, items):
self.items = set(items)
def __contains__(self, item):
return item in self.items
my_set = MySet([1, 2, 3])
print(2 in my_set) # 使用了__contains__方法
print(4 in my_set) # 使用了__contains__方法
输出结果
10-__call__(self, ...)
允许一个实例像函数一样被调用。
class ComplexNumber:
def __init__(self, real, imag):
self.real = real
self.imag = imag
# 加法
def __add__(self, other):
return ComplexNumber(self.real + other.real, self.imag + other.imag)
# 减法
def __sub__(self, other):
return ComplexNumber(self.real - other.real, self.imag - other.imag)
# 乘法
def __mul__(self, other):
real = self.real * other.real - self.imag * other.imag
imag = self.real * other.imag + self.imag * other.real
return ComplexNumber(real, imag)
# 除法
def __truediv__(self, other):
denom = other.real ** 2 + other.imag ** 2
real = (self.real * other.real + self.imag * other.imag) / denom
imag = (self.imag * other.real - self.real * other.imag) / denom
return ComplexNumber(real, imag)
def __str__(self):
return f"{self.real} {'+' if self.imag >= 0 else '-'} {abs(self.imag)}i"
# 测试代码
c1 = ComplexNumber(3, 2)
print(f'c1={c1}')
c2 = ComplexNumber(1, 7)
print(f'c2={c2}')
print(c1 + c2)
print(c1 - c2)
print(c1 * c2)
print(c1 / c2)
输出结果
11-__eq__(self, other)` 等比较方法
如`__eq__`、`__ne__`、`__lt__`、`__le__`、`__gt__`、`__ge__`等,定义了对象之间如何进行比较。
class Number:
def __init__(self, value):
self.value = value
def __eq__(self, other):
return self.value == other.value
def __lt__(self, other):
return self.value < other.value
n1 = Number(1)
n2 = Number(2)
print(n1 < n2) # 使用了__lt__方法
print(n1 == n2) # 使用了__eq__方法
输出结果
12-__add__(self, other)` 等数值运算方法
如`__add__`、`__sub__`、`__mul__`、`__truediv__`等,允许对象参与算术运算。
13-__enter__(self)` 和 `__exit__(self, exc_type, exc_val, exc_tb)
实现上下文管理协议,支持`with`语句。
4-练习题
4-1-实现一个复数类
创建一个名为`ComplexNumber`的类,该类支持以下操作:
- 加法:`c1 + c2`
- 减法:`c1 - c2`
- 乘法:`c1 * c2`
- 除法:`c1 / c2`
- 字符串表示:使用`__str__`或`__repr__`方法使对象打印为易于阅读的形式,如`"3 + 4i"`
class ComplexNumber:
def __init__(self, real, imag):
self.real = real
self.imag = imag
# 加法
def __add__(self, other):
return ComplexNumber(self.real + other.real, self.imag + other.imag)
# 减法
def __sub__(self, other):
return ComplexNumber(self.real - other.real, self.imag - other.imag)
# 乘法
def __mul__(self, other):
real = self.real * other.real - self.imag * other.imag
imag = self.real * other.imag + self.imag * other.real
return ComplexNumber(real, imag)
# 除法
def __truediv__(self, other):
denom = other.real**2 + other.imag**2
real = (self.real * other.real + self.imag * other.imag) / denom
imag = (self.imag * other.real - self.real * other.imag) / denom
return ComplexNumber(real, imag)
def __str__(self):
return f"{self.real} {'+' if self.imag >= 0 else '-'} {abs(self.imag)}i"
# 测试代码
c1 = ComplexNumber(3, 2)
c2 = ComplexNumber(1, 7)
print(c1 + c2)
print(c1 - c2)
print(c1 * c2)
print(c1 / c2)
4-2-创建一个可迭代的斐波那契数列生成器
创建一个名为`Fibonacci`的类,该类可以作为一个可迭代对象来生成斐波那契数列。要求实现`__iter__`和`__next__`方法,并且在达到指定的最大项数时停止迭代。
class Fibonacci:
def __init__(self, max_count):
self.max_count = max_count
self.count = 0
self.a, self.b = 0, 1
def __iter__(self):
return self
def __next__(self):
if self.count < self.max_count:
result = self.a
self.a, self.b = self.b, self.a + self.b
self.count += 1
return result
else:
raise StopIteration
# 测试代码
fib = Fibonacci(10)
for num in fib:
print(num, end=" ")
完成这些练习可以帮助你更好地理解如何使用Python的魔法方法来增强你的类的功能。尝试自己编写代码并测试它们,看看是否能得到预期的结果。如果有任何问题或需要进一步的帮助,请随时提问!
关注小红书 什么IT 943707791
什么IT