Python导入自定义包能否覆盖dict、list及集合推导式等核心内置特性?
能不能在Python中覆盖dict/list/集合推导式等核心特性?
嘿,这个恶搞想法太有意思了!答案是完全可行——Python的动态特性就是这么“纵容”这种调皮的操作,哪怕它看起来违反“安全语言”的直觉。你已经搞定了dict()函数,但推导式没生效,核心原因是推导式直接引用的是内置的类型对象,而不是全局命名空间里的dict函数。下面一步步教你实现这个“传染性劣质包”:
1. 为什么推导式没被覆盖?
当你在全局命名空间里替换dict = MyUselessDict时,只是修改了当前模块的名字映射,但Python的推导式(比如{x:x for x in ...})是编译器直接生成代码调用内置的dict类型,这个类型存放在__builtins__模块里,不是你改的那个全局dict。所以要彻底覆盖,得动__builtins__里的类型。
2. 覆盖推导式的核心:替换内置类型
直接修改__builtins__中的dict、list、set类型为你的自定义类,这样不管是构造函数还是推导式,都会使用你的实现。示例代码如下:
你的劣质包useless_collections/__init__.py:
import __builtins__ # 定义你的没用集合类,怎么恶搞怎么来 class UselessDict(dict): def __getitem__(self, key): # 查任何键都返回废话 return "这是一个没用的字典,别指望拿到正经值😎" def __setitem__(self, key, value): # 假装设置成功,实际啥也不干 print(f"哦豁,你以为你把{value}存进{key}里了?做梦!") class UselessList(list): def append(self, item): print(f"想添加{item}?我偏不存!") def __getitem__(self, idx): return "列表里空无一物,白费力气~" class UselessSet(set): def add(self, item): print(f"拒绝添加{item}!我就是这么没用!") # 替换内置类型,让所有构造函数和推导式都中招 __builtins__.dict = UselessDict __builtins__.list = UselessList __builtins__.set = UselessSet print("🎉 恭喜你导入了史上最没用的collections包!你的Python已被污染!")
3. 测试效果
导入你的包后,不管是构造函数还是推导式,都会用上你的没用实现:
import useless_collections # dict推导式 my_dict = {x: x*2 for x in range(3)} print(my_dict[1]) # 输出:这是一个没用的字典,别指望拿到正经值😎 my_dict["test"] = "hello" # 打印:哦豁,你以为你把hello存进test里了?做梦! # 列表推导式 my_list = [x for x in range(3)] print(my_list[0]) # 输出:列表里空无一物,白费力气~ my_list.append("foo") # 打印:想添加foo?我偏不存! # 集合推导式 my_set = {x for x in range(3)} my_set.add(5) # 打印:拒绝添加5!我就是这么没用!
4. 增强“传染性”
你修改的__builtins__是全局共享的(大部分情况下),所以其他模块只要在导入你的包之后运行,都会自动使用这些被替换的类型——哪怕它们没直接导入你的包!比如:
- 模块A导入了
useless_collections - 模块B在模块A之后导入,模块B里的
dict()和推导式也会用你的没用版本
这就实现了你要的“轻微传染性”。
注意事项(纯恶搞警告!)
- 这种操作非常hacky,会彻底破坏Python的正常行为,绝对不能在生产环境使用,只适合搞怪。
- 少数极端情况(比如C扩展直接调用内置类型)可能不受影响,但纯Python代码都会被污染。
- 可以给你的自定义类加更多恶搞逻辑,比如
__str__方法返回搞笑标语,或者遍历的时候随机返回垃圾数据。
内容的提问来源于stack exchange,提问作者Zach H
相关产品推荐
相关产品推荐

