Python 2.x gotchas and landmines

后端 未结 23 2194
北恋
北恋 2020-11-28 17:47

The purpose of my question is to strengthen my knowledge base with Python and get a better picture of it, which includes knowing its faults and surprises. To keep things sp

相关标签:
23条回答
  • 2020-11-28 18:27

    Dynamic binding makes typos in your variable names surprisingly hard to find. It's easy to spend half an hour fixing a trivial bug.

    EDIT: an example...

    for item in some_list:
        ... # lots of code
    ... # more code
    for tiem in some_other_list:
        process(item) # oops!
    
    0 讨论(0)
  • 2020-11-28 18:29

    Loops and lambdas (or any closure, really): variables are bound by name

    funcs = []
    for x in range(5):
      funcs.append(lambda: x)
    
    [f() for f in funcs]
    # output:
    # 4 4 4 4 4
    

    A work around is either creating a separate function or passing the args by name:

    funcs = []
    for x in range(5):
      funcs.append(lambda x=x: x)
    [f() for f in funcs]
    # output:
    # 0 1 2 3 4
    
    0 讨论(0)
  • 2020-11-28 18:29

    Unintentionally mixing oldstyle and newstyle classes can cause seemingly mysterious errors.

    Say you have a simple class hierarchy consisting of superclass A and subclass B. When B is instantiated, A's constructor must be called first. The code below correctly does this:

    class A(object):
        def __init__(self):
            self.a = 1
    
    class B(A):
        def __init__(self):
            super(B, self).__init__()
            self.b = 1
    
    b = B()
    

    But if you forget to make A a newstyle class and define it like this:

    class A:
        def __init__(self):
            self.a = 1
    

    you get this traceback:

    Traceback (most recent call last):
      File "AB.py", line 11, in <module>
        b = B()
      File "AB.py", line 7, in __init__
        super(B, self).__init__()
    TypeError: super() argument 1 must be type, not classobj
    

    Two other questions relating to this issue are 489269 and 770134

    0 讨论(0)
  • 2020-11-28 18:29

    Using class variables when you want instance variables. Most of the time this doesn't cause problems, but if it's a mutable value it causes surprises.

    class Foo(object):
        x = {}
    

    But:

    >>> f1 = Foo()
    >>> f2 = Foo()
    >>> f1.x['a'] = 'b'
    >>> f2.x
    {'a': 'b'}
    

    You almost always want instance variables, which require you to assign inside __init__:

    class Foo(object):
        def __init__(self):
            self.x = {}
    
    0 讨论(0)
  • 2020-11-28 18:30

    Floats are not printed at full precision by default (without repr):

    x = 1.0 / 3
    y = 0.333333333333
    print x  #: 0.333333333333
    print y  #: 0.333333333333
    print x == y  #: False
    

    repr prints too many digits:

    print repr(x)  #: 0.33333333333333331
    print repr(y)  #: 0.33333333333300003
    print x == 0.3333333333333333  #: True
    
    0 讨论(0)
提交回复
热议问题