Python编程语言中有哪些鲜为人知但很有用的特性?

尽量将答案限制在Python核心。 每个回答一个特征。 给出一个例子和功能的简短描述,而不仅仅是文档链接。 使用标题作为第一行标记该特性。

快速链接到答案:

参数解包 牙套 链接比较运算符 修饰符 可变默认参数的陷阱/危险 描述符 字典默认的.get值 所以测试 省略切片语法 枚举 其他/ 函数作为iter()参数 生成器表达式 导入该 就地值交换 步进列表 __missing__物品 多行正则表达式 命名字符串格式化 嵌套的列表/生成器推导 运行时的新类型 .pth文件 ROT13编码 正则表达式调试 发送到发电机 交互式解释器中的制表符补全 三元表达式 试着/ / else除外 拆包+打印()函数 与声明


当前回答

如果你在你的应用程序中重命名了一个类,你正在通过Pickle加载用户保存的文件,而其中一个重命名的类存储在用户的旧保存中,你将不能加载这个Pickle文件。

然而,只要在你的类定义中添加一个引用,一切就好了:

例如,:

class Bleh:
    pass

现在,

class Blah:
    pass

所以,你的用户的pickle保存的文件包含一个Bleh的引用,它不存在,由于重命名。这是固定的吗?

Bleh = Blah

简单!

其他回答

博格模式

这是亚历克斯·马尔泰利的杀手。所有Borg实例共享状态。这消除了使用单例模式的需要(共享状态时实例无关紧要),而且相当优雅(但使用新类会更加复杂)。

foo的值可以在任何实例中重新赋值,所有值都将被更新,你甚至可以重新赋值整个字典。博格是个完美的名字,点击这里阅读更多。

class Borg:
    __shared_state = {'foo': 'bar'}
    def __init__(self):
        self.__dict__ = self.__shared_state
    # rest of your class here

这非常适合共享eventlet。GreenPool控制并发。

您可以用元类重写类的mro

>>> class A(object):
...     def a_method(self):
...         print("A")
... 
>>> class B(object):
...     def b_method(self):
...         print("B")
... 
>>> class MROMagicMeta(type):
...     def mro(cls):
...         return (cls, B, object)
... 
>>> class C(A, metaclass=MROMagicMeta):
...     def c_method(self):
...         print("C")
... 
>>> cls = C()
>>> cls.c_method()
C
>>> cls.a_method()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute 'a_method'
>>> cls.b_method()
B
>>> type(cls).__bases__
(<class '__main__.A'>,)
>>> type(cls).__mro__
(<class '__main__.C'>, <class '__main__.B'>, <class 'object'>)

藏起来可能是有原因的。:)

对象实例的方法替换

您可以替换已经创建的对象实例的方法。它允许你创建具有不同(例外)功能的对象实例:

>>> class C(object):
...     def fun(self):
...         print "C.a", self
...
>>> inst = C()
>>> inst.fun()  # C.a method is executed
C.a <__main__.C object at 0x00AE74D0>
>>> instancemethod = type(C.fun)
>>>
>>> def fun2(self):
...     print "fun2", self
...
>>> inst.fun = instancemethod(fun2, inst, C)  # Now we are replace C.a by fun2
>>> inst.fun()  # ... and fun2 is executed
fun2 <__main__.C object at 0x00AE74D0>

C.a在inst实例中被fun2()取代(self没有改变)。

或者,我们也可以使用new模块,但它自Python 2.6起就被贬低了:

>>> def fun3(self):
...     print "fun3", self
...
>>> import new
>>> inst.fun = new.instancemethod(fun3, inst, C)
>>> inst.fun()
fun3 <__main__.C object at 0x00AE74D0>

节点:这个解决方案不应该被用作继承机制的一般替代!但在某些特定的情况下(调试、模拟),它可能非常方便。

警告:此解决方案不适用于内置类型和使用插槽的新样式类。

模块操作符中的Getter函数

模块操作符中的函数attrgetter()和itemgetter()可用于生成用于排序和搜索对象和字典的快速访问函数

Python库文档中的第6.7章

以完全动态的方式创建新类型

>>> NewType = type("NewType", (object,), {"x": "hello"})
>>> n = NewType()
>>> n.x
"hello"

哪个是完全一样的

>>> class NewType(object):
>>>     x = "hello"
>>> n = NewType()
>>> n.x
"hello"

可能不是最有用的东西,但很高兴知道。

编辑:新类型的固定名称,应该是NewType,是与类语句完全相同的东西。

编辑:调整标题,以更准确地描述功能。