python: Este é um lugar onde devemos ter cuidado.

Autora:Ilídan, Criado: 2016-12-29 13:46:12, Atualizado:

python: Este é um lugar onde devemos ter cuidado.

python是一门非常有趣的语言。它提供了许多非常方便的标准库和许多内置命令是我们轻松完成任务.但是好东西太多了就有选择恐惧症了,以至于我们不能很好第利用这个标准库和它的基本机构。下面列出了一些对python新手来说很简单有效的陷阱。

  • Ignorando a versão do Python

    Este é um problema que vem sendo levantado constantemente no StackOverflow. Como é uma experiência quando seu código perfeito é executado em um computador de outra pessoa, é preciso verificar se suas versões de Python são iguais. Certifique-se de que o código é executado em uma versão de Python que você conhece.

    $ python --version
    Python 2.7.9
    

    Gerenciamento de versões do Python

    O pyenv é um bom gerenciador de versões do Python. Infelizmente, ele só funciona no sistema *nix. No Mac OS, você pode simplesmente instalar o pyenv com o brew install. No sistema Linux, há um instalador automático.

  • Enredado em resolver todos os problemas com uma linha de código

    Muitas pessoas se gabam de que eu resolvi todos os problemas com uma única linha de código, mesmo que o seu código seja menos eficiente do que o normal, e que o código seja mais difícil de ler e até mesmo confuso.

    l = [m for a, b in zip(this, that) if b.method(a) != b for m in b if not m.method(a, b) and reduce(lambda x, y: a + y.method(), (m, a, b))]
    

    Para ser honesto, o código acima foi escrito por mim mesmo para demonstrar isso. Mas eu realmente vi muitas pessoas fazendo isso. Se você simplesmente se mostrar como um meio de resolver problemas complexos adicionando coisas a uma lista ou um conjunto, você pode não ser recompensado.

    Uma linha de controle de código não é uma grande conquista, embora às vezes pareça particularmente inteligente.

  • Set initializado erroneamente

    这是一个更加微妙的问题,有时候会让你措手不及。set推导式起来有点像list推导式.

    >>> { n for n in range(10) if n % 2 == 0 }
    {0, 8, 2, 4, 6}
    >>> type({ n for n in range(10) if n % 2 == 0 })
    

    O exemplo acima mostra isso. O set é um pouco como colocar uma lista em um recipiente. A diferença entre eles é que o conjunto não tem valores repetidos e é desordenado.

    >>> {}
    {}
    >>> type({})
    

    Então, se quisermos inicializar um conjunto vazio, vamos usar o conjunto direto.

    >>> set()
    set()
    >>> type(set())
    

    Observe que um conjunto vazio pode ser representado como um conjunto (((), mas é um conjunto que contém elementos que devem ser definidos como um conjunto (([1, 2]) ).

  • Não entendem o GIL

    GIL (global interpreter lock) significa que somente um thread pode ser executado em um programa Python a qualquer momento. Isso significa que quando não podemos criar um thread e esperar que ele seja executado em paralelo. O que o interprete Python realmente faz é trocar rapidamente linhas de execução diferentes. Mas esta é uma versão muito simples.

    Muitas pessoas tentam justificar o Python dizendo que são todos linhas reais.3. Isso é verdade, mas não muda o fato de que o Python lida com linhas de maneira diferente do que você espera.

    A solução proposta é usar módulos de multiprocessamento. Os processos fornecidos pelos módulos de multiprocessamento podem basicamente cobrir bem as diferenças. No entanto, as diferenças são muito mais altas do que o custo do fio.

    No entanto, este problema não é encontrado em todos os programas Python. PyPy-stm é um exemplo de uma implementação Python que não é afetada pelo GIL. Implementações construídas em outras plataformas, como JVM (Jython) ou CLR (IronPython), não têm problemas com o GIL.

    Em suma, cuidado com o uso de classes de threads, você pode não estar recebendo o que você quer.

  • Usando classes de estilo obsoletas

    No Python 2, existem dois tipos de classes, um casco antigo e um casco de estilo novo. Se você estiver usando o Python 3, você está usando o casco de estilo novo por padrão. Para garantir que você use o casco de estilo novo no Python 2, você precisa herdar object ou qualquer nova classe que você crie.

    class MyNewObject(object): # stuff here
    

    Estes novos blocos corrigem alguns problemas muito básicos que ocorrem nas classes antigas, se você estiver interessado, pode ver a documentação.

  • Irritação errada

    Os seguintes erros são muito comuns para os iniciantes:

    for name_index in range(len(names)):
      print(names[name_index])
    

    Obviamente, não é necessário usar len, e, na verdade, percorrer a lista pode ser feito com uma frase muito simples:

    for name in names:
       print(name)  
    

    Além disso, há uma série de outras ferramentas disponíveis para você trabalhar com a simplificação da iteração. Por exemplo, o zip pode ser usado para percorrer duas listas:

    for cat, dog in zip(cats, dogs):
       print(cat, dog)
    

    Se quisermos considerar as variáveis de índices e de listas de valores, podemos usar o enumerate.

    for index, cat in enumerate(cats):
       print(cat, index)
    

    O iterools também tem muitas outras funções para você escolher. Se o iterools tiver uma função que você quer, é muito fácil de obter.

    O uso indevido de itertools fez com que um grande deus no StackOverflow gastou muito tempo para resolvê-lo.

    Usando parâmetros padrão variáveis

    Eu vi muitas coisas como:

    def foo(a, b, c=[]):
       # append to c
       # do some more stuff
    

    Não use parâmetros padrão variáveis, mas use:

    def foo(a, b, c=None):
     if c is None:
       c = []
       # append to c
       # do some more stuff 
    

    O exemplo a seguir pode ajudar-nos a entender o problema de forma intuitiva:

    In[2]: def foo(a, b, c=[]):
    ...     c.append(a)
    ...     c.append(b)
    ...     print(c)
    ...
    In[3]: foo(1, 1)
    [1, 1]
    In[4]: foo(1, 1)
    [1, 1, 1, 1]
    In[5]: foo(1, 1)
    [1, 1, 1, 1, 1, 1]
    

    A mesma c é citada repetidamente cada vez que a função é chamada. Isso pode ter algumas consequências muito indesejadas.


Mais.