Python 类的8个冷知识

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 的面向对象机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王小玗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值