zoukankan      html  css  js  c++  java
  • Python惯用法

    1. 不要使用可变类型作为参数的默认值

    摘自《流畅的Python》8.4.1

    class HauntedBus:
        """备受幽灵乘客折磨的校车"""
        def __init__(self, passengers=[]):
            self.passengers = passengers
    
        def pick(self, name):
            self.passengers.append(name)
    
        def drop(self, name):
            self.passengers.remove(name)
    

    运行测试用例

    >>> bus1 = HauntedBus(['Alice', 'Bill'])
    >>> bus1.passengers
    ['Alice', 'Bill']
    >>> bus1.pick('Charlie')
    >>> bus1.drop('Alice')
    >>> bus1.passengers
    ['Bill', 'Charlie']
    >>> bus2 = HauntedBus()
    >>> bus2.pick('Carrie')
    >>> bus2.passengers
    ['Carrie']
    >>> bus3 = HauntedBus()
    >>> bus3.passengers
    ['Carrie']
    >>> bus3.pick('Dave')
    >>> bus2.passengers
    ['Carrie', 'Dave']
    >>> bus2.passengers is bus3.passengers
    True
    >>> bus1.passengers
    ['Bill', 'Charlie']
    

    问题来了:登上 bus3 的 Dave 出现在 bus2 中。

    原因在于,bus2.passengers 和 bus3.passengers 指代同一个列表。即没有指定初始乘客的 HauntedBus 实例会共享同一个乘客列表。

    出现这个问题的根源是,默认值在定义函数时计算(通常在加载模块时),因此默认值变成了函数对象的属性。因此,如果默认值是可变对象,而且修改了它的值,那么后续的函数调用都会受到影响。

    可以通过 __defaults__ 属性中的那些幽灵学生:

    >>> dir(HauntedBus.__init__)  # doctest: +ELLIPSIS
    ['__annotations__', '__call__', ..., '__defaults__', ...]
    >>> HauntedBus.__init__.__defaults__
    (['Carrie', 'Dave'],)
    

    可变默认值导致的这个问题说明了为什么通常使用 None 作为接收可变值的参数的默认
    值。

  • 相关阅读:
    POJ1222_EXTENDED LIGHTS OUT
    SGU196_Matrix Multiplication
    ZOJ3772_Calculate the Function
    Triangle POJ
    POJ 2187 Beauty Contest(凸包,旋转卡壳)
    [Neerc2016]Mole Tunnels (模拟费用流)
    [2019ccpc网络赛】K-th occurrence(后缀数组+主席树)
    【HDU2019多校】E
    Gym
    P3160 [CQOI2012]局部极小值(dfs+状压dp)
  • 原文地址:https://www.cnblogs.com/brt2/p/12982113.html
Copyright © 2011-2022 走看看