Python 类的冷知识
以下是一些关于 Python 类的不太为人所知但有趣的特性:
1. 类可以动态修改基类
即使在类创建后,你也可以修改它的基类:
class A:
def method(self):
return "A"
class B:
def method(self):
return "B"
class C(A):
pass
obj = C()
print(obj.method()) # 输出: A
C.__bases__ = (B,) # 修改基类
print(obj.method()) # 输出: B
2. 类可以拦截实例的删除
使用 __del__ 方法可以在实例被垃圾回收时执行代码:
class Life:
def __del__(self):
print("Goodbye, cruel world!")
obj = Life()
del obj # 输出: Goodbye, cruel world!
3. 类可以作为装饰器
因为类是可调用的(实现了 __call__ 方法),所以它们可以用作装饰器:
class Decorator:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("Before call")
result = self.func(*args, **kwargs)
print("After call")
return result
@Decorator
def say_hello():
print("Hello!")
say_hello()
4. 实例方法可以临时变为静态方法
使用 __func__ 可以访问方法的原始函数:
class MyClass:
def method(self):
return "instance method called"
obj = MyClass()
# 临时将实例方法当作静态方法使用
print(MyClass.method.__func__(None)) # 输出: instance method called
5. 类可以定义 __prepare__ 方法
在 Python 3 中,元类可以定义 __prepare__ 方法来控制类命名空间的创建:
from collections import OrderedDict
class OrderedMeta(type):
@classmethod
def __prepare__(cls, name, bases):
return OrderedDict()
def __new__(cls, name, bases, namespace):
namespace['order_of_attributes'] = list(namespace.keys())
return super().__new__(cls, name, bases, namespace)
class MyClass(metaclass=OrderedMeta):
method1 = lambda self: None
method2 = lambda self: None
print(MyClass.order_of_attributes) # 输出: ['__module__', '__qualname__', 'method1', 'method2']
6. 类可以阻止属性创建
使用 __slots__ 可以阻止动态创建新属性:
class Restricted:
__slots__ = ['allowed']
def __init__(self):
self.allowed = 42
obj = Restricted()
obj.allowed = 100
obj.new_attr = 50 # 引发 AttributeError
7. 类可以自定义布尔值转换
通过 __bool__ 或 __len__ 方法可以自定义实例的布尔值:
class Truthy:
def __bool__(self):
return False
obj = Truthy()
print(bool(obj)) # 输出: False
8. 类可以拦截未定义的方法调用
使用 __getattr__ 可以拦截对未定义属性的访问:
class CatchAll:
def __getattr__(self, name):
return f"You tried to access {name}"
obj = CatchAll()
print(obj.some_random_attr) # 输出: You tried to access some_random_attr
这些冷知识展示了 Python 类系统的灵活性和强大功能,虽然在实际开发中不一定常用,但了解它们可以帮助你更深入地理解 Python 的面向对象机制。


1450

被折叠的 条评论
为什么被折叠?



